1*9a0e4156SSadaf Ebrahimi# Capstone-Engine API Documentation
2*9a0e4156SSadaf Ebrahimi
3*9a0e4156SSadaf Ebrahimi| Version | 4.0.2 |
4*9a0e4156SSadaf Ebrahimi| ------- | ----- |
5*9a0e4156SSadaf Ebrahimi
6*9a0e4156SSadaf Ebrahimi**Official API document by [kabeor](https://github.com/kabeor)**
7*9a0e4156SSadaf Ebrahimi
8*9a0e4156SSadaf Ebrahimi[Capstone Engine](https://github.com/capstone-engine/capstone)是一个支持多种硬件架构的二进制反汇编引擎。
9*9a0e4156SSadaf Ebrahimi
10*9a0e4156SSadaf Ebrahimi
11*9a0e4156SSadaf Ebrahimi## 0x0 开发准备
12*9a0e4156SSadaf Ebrahimi
13*9a0e4156SSadaf Ebrahimi  Capstone官网: http://www.capstone-engine.org
14*9a0e4156SSadaf Ebrahimi
15*9a0e4156SSadaf Ebrahimi### 自行编译lib和dll方法
16*9a0e4156SSadaf Ebrahimi
17*9a0e4156SSadaf Ebrahimi  源码: https://github.com/capstone-engine/capstone.git
18*9a0e4156SSadaf Ebrahimi
19*9a0e4156SSadaf Ebrahimi  git clone下来
20*9a0e4156SSadaf Ebrahimi  文件结构如下:
21*9a0e4156SSadaf Ebrahimi
22*9a0e4156SSadaf Ebrahimi```
23*9a0e4156SSadaf Ebrahimi   .                <- 主要引擎core engine + README + 编译文档COMPILE.TXT24*9a0e4156SSadaf Ebrahimi├── arch            <- 各语言反编译支持的代码实现
25*9a0e4156SSadaf Ebrahimi│   ├── AArch64     <- ARM64 (aka ARMv8) 引擎
26*9a0e4156SSadaf Ebrahimi│   ├── ARM         <- ARM 引擎
27*9a0e4156SSadaf Ebrahimi│   ├── EVM         <- Ethereum 引擎
28*9a0e4156SSadaf Ebrahimi│   ├── M680X       <- M680X 引擎
29*9a0e4156SSadaf Ebrahimi│   ├── M68K        <- M68K 引擎
30*9a0e4156SSadaf Ebrahimi|   ├── MOS65XX     <- MOS65XX 引擎
31*9a0e4156SSadaf Ebrahimi│   ├── Mips        <- Mips 引擎
32*9a0e4156SSadaf Ebrahimi│   ├── PowerPC     <- PowerPC 引擎
33*9a0e4156SSadaf Ebrahimi│   ├── Sparc       <- Sparc 引擎
34*9a0e4156SSadaf Ebrahimi│   ├── SystemZ     <- SystemZ 引擎
35*9a0e4156SSadaf Ebrahimi│   ├── TMS320C64x  <- TMS320C64x 引擎
36*9a0e4156SSadaf Ebrahimi│   ├── X86         <- X86 引擎
37*9a0e4156SSadaf Ebrahimi│   └── XCore       <- XCore 引擎
38*9a0e4156SSadaf Ebrahimi├── bindings        <- 绑定
39*9a0e4156SSadaf Ebrahimi│   ├── java        <- Java 绑定 + 测试代码
40*9a0e4156SSadaf Ebrahimi│   ├── ocaml       <- Ocaml 绑定 + 测试代码
41*9a0e4156SSadaf Ebrahimi│   ├── powershell  <- powershell 绑定 + 测试代码
42*9a0e4156SSadaf Ebrahimi│   ├── python      <- python 绑定 + 测试代码
43*9a0e4156SSadaf Ebrahimi│   └── vb6         <- vb6 绑定 + 测试代码
44*9a0e4156SSadaf Ebrahimi├── contrib         <- 社区代码
45*9a0e4156SSadaf Ebrahimi├── cstool          <- Cstool 检测工具源码
46*9a0e4156SSadaf Ebrahimi├── docs            <- 文档,主要是capstone的实现思路
47*9a0e4156SSadaf Ebrahimi├── include         <- C头文件
48*9a0e4156SSadaf Ebrahimi├── msvc            <- Microsoft Visual Studio 支持(Windows)
49*9a0e4156SSadaf Ebrahimi├── packages        <- Linux/OSX/BSD50*9a0e4156SSadaf Ebrahimi├── suite           <- 项目开发所需工具
51*9a0e4156SSadaf Ebrahimi├── tests           <- C语言测试用例
52*9a0e4156SSadaf Ebrahimi├── windows         <- Windows 支持(Windows内核驱动编译)
53*9a0e4156SSadaf Ebrahimi├── windowsce       <- Windows CE 支持
54*9a0e4156SSadaf Ebrahimi└── xcode           <- Xcode 支持 (MacOSX 编译)
55*9a0e4156SSadaf Ebrahimi```
56*9a0e4156SSadaf Ebrahimi
57*9a0e4156SSadaf Ebrahimi下面演示Windows10使用Visual Studio2019编译
58*9a0e4156SSadaf Ebrahimi
59*9a0e4156SSadaf Ebrahimi复制msvc文件夹到一个比较清爽的位置,内部结构如下:
60*9a0e4156SSadaf Ebrahimi
61*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/1.jpg)
62*9a0e4156SSadaf Ebrahimi
63*9a0e4156SSadaf EbrahimiVS打开capstone.sln项目文件,解决方案自动载入这些
64*9a0e4156SSadaf Ebrahimi
65*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/2.jpg)
66*9a0e4156SSadaf Ebrahimi
67*9a0e4156SSadaf Ebrahimi可以看到支持的所有语言都在这里了,如果都需要的话,直接编译就好了,只需要其中几种,则右键解决方案->属性->配置属性  如下
68*9a0e4156SSadaf Ebrahimi
69*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/3.jpg)
70*9a0e4156SSadaf Ebrahimi
71*9a0e4156SSadaf Ebrahimi生成选项中勾选你需要的支持项即可
72*9a0e4156SSadaf Ebrahimi编译后会在当前文件夹Debug目录下生成capstone.lib静态编译库和capstone.dll动态库这样就可以开始使用Capstone进行开发了
73*9a0e4156SSadaf Ebrahimi
74*9a0e4156SSadaf Ebrahimi如果不想自己编译,官方也提供了官方编译版本
75*9a0e4156SSadaf Ebrahimi
76*9a0e4156SSadaf EbrahimiWin32: https://github.com/capstone-engine/capstone/releases/download/4.0.2/capstone-4.0.2-win32.zip
77*9a0e4156SSadaf Ebrahimi
78*9a0e4156SSadaf EbrahimiWin64: https://github.com/capstone-engine/capstone/releases/download/4.0.2/capstone-4.0.2-win64.zip
79*9a0e4156SSadaf Ebrahimi
80*9a0e4156SSadaf Ebrahimi选x32或x64将影响后面开发的位数
81*9a0e4156SSadaf Ebrahimi
82*9a0e4156SSadaf Ebrahimi
83*9a0e4156SSadaf Ebrahimi
84*9a0e4156SSadaf Ebrahimi### 引擎调用测试
85*9a0e4156SSadaf Ebrahimi
86*9a0e4156SSadaf Ebrahimi新建一个VS项目,将capstone\include\capstone中的头文件以及编译好的lib和dll文件全部拷贝到新建项目的主目录下
87*9a0e4156SSadaf Ebrahimi
88*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/4.jpg)
89*9a0e4156SSadaf Ebrahimi
90*9a0e4156SSadaf Ebrahimi在VS解决方案中,头文件添加现有项capstone.h,资源文件中添加capstone.lib,重新生成解决方案
91*9a0e4156SSadaf Ebrahimi
92*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/5.jpg)
93*9a0e4156SSadaf Ebrahimi
94*9a0e4156SSadaf Ebrahimi那么现在来测试一下我们自己的capstone引擎吧
95*9a0e4156SSadaf Ebrahimi
96*9a0e4156SSadaf Ebrahimi主文件写入如下代码
97*9a0e4156SSadaf Ebrahimi
98*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
99*9a0e4156SSadaf Ebrahimi
100*9a0e4156SSadaf Ebrahimi```c++
101*9a0e4156SSadaf Ebrahimi#include <iostream>
102*9a0e4156SSadaf Ebrahimi#include <stdio.h>
103*9a0e4156SSadaf Ebrahimi#include <cinttypes>
104*9a0e4156SSadaf Ebrahimi#include "capstone.h"
105*9a0e4156SSadaf Ebrahimiusing namespace std;
106*9a0e4156SSadaf Ebrahimi
107*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00"
108*9a0e4156SSadaf Ebrahimi
109*9a0e4156SSadaf Ebrahimiint main(void)
110*9a0e4156SSadaf Ebrahimi{
111*9a0e4156SSadaf Ebrahimi	csh handle;
112*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
113*9a0e4156SSadaf Ebrahimi	size_t count;
114*9a0e4156SSadaf Ebrahimi
115*9a0e4156SSadaf Ebrahimi	if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) {
116*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to initialize engine!\n");
117*9a0e4156SSadaf Ebrahimi		return -1;
118*9a0e4156SSadaf Ebrahimi	}
119*9a0e4156SSadaf Ebrahimi
120*9a0e4156SSadaf Ebrahimi	count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn);
121*9a0e4156SSadaf Ebrahimi	if (count) {
122*9a0e4156SSadaf Ebrahimi		size_t j;
123*9a0e4156SSadaf Ebrahimi
124*9a0e4156SSadaf Ebrahimi		for (j = 0; j < count; j++) {
125*9a0e4156SSadaf Ebrahimi			printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
126*9a0e4156SSadaf Ebrahimi		}
127*9a0e4156SSadaf Ebrahimi
128*9a0e4156SSadaf Ebrahimi		cs_free(insn, count);
129*9a0e4156SSadaf Ebrahimi	}
130*9a0e4156SSadaf Ebrahimi	else
131*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to disassemble given code!\n");
132*9a0e4156SSadaf Ebrahimi
133*9a0e4156SSadaf Ebrahimi	cs_close(&handle);
134*9a0e4156SSadaf Ebrahimi
135*9a0e4156SSadaf Ebrahimi	return 0;
136*9a0e4156SSadaf Ebrahimi}
137*9a0e4156SSadaf Ebrahimi```
138*9a0e4156SSadaf Ebrahimi
139*9a0e4156SSadaf Ebrahimi</details>
140*9a0e4156SSadaf Ebrahimi
141*9a0e4156SSadaf Ebrahimi运行结果
142*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/6.jpg)
143*9a0e4156SSadaf Ebrahimi
144*9a0e4156SSadaf Ebrahimi
145*9a0e4156SSadaf Ebrahimi
146*9a0e4156SSadaf Ebrahimi## 0x1 数据类型
147*9a0e4156SSadaf Ebrahimi
148*9a0e4156SSadaf Ebrahimi### csh
149*9a0e4156SSadaf Ebrahimi
150*9a0e4156SSadaf Ebrahimi用于生成调用capstone API的句柄
151*9a0e4156SSadaf Ebrahimi
152*9a0e4156SSadaf Ebrahimi```cpp
153*9a0e4156SSadaf Ebrahimisize_t csh
154*9a0e4156SSadaf Ebrahimi```
155*9a0e4156SSadaf Ebrahimi
156*9a0e4156SSadaf Ebrahimi> 用法: `csh handle;`
157*9a0e4156SSadaf Ebrahimi
158*9a0e4156SSadaf Ebrahimi
159*9a0e4156SSadaf Ebrahimi### cs_arch
160*9a0e4156SSadaf Ebrahimi
161*9a0e4156SSadaf Ebrahimi架构选择
162*9a0e4156SSadaf Ebrahimi
163*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
164*9a0e4156SSadaf Ebrahimi
165*9a0e4156SSadaf Ebrahimi```cpp
166*9a0e4156SSadaf Ebrahimi enum cs_arch {
167*9a0e4156SSadaf Ebrahimi	CS_ARCH_ARM = 0,	///< ARM 架构 (包括 Thumb, Thumb-2)
168*9a0e4156SSadaf Ebrahimi	CS_ARCH_ARM64,		///< ARM-64, 也叫 AArch64
169*9a0e4156SSadaf Ebrahimi	CS_ARCH_MIPS,		///< Mips 架构
170*9a0e4156SSadaf Ebrahimi   CS_ARCH_X86,		///< X86 架构 (包括 x86 & x86-64)
171*9a0e4156SSadaf Ebrahimi	CS_ARCH_PPC,		///< PowerPC 架构
172*9a0e4156SSadaf Ebrahimi	CS_ARCH_SPARC,		///< Sparc 架构
173*9a0e4156SSadaf Ebrahimi	CS_ARCH_SYSZ,		///< SystemZ 架构
174*9a0e4156SSadaf Ebrahimi	CS_ARCH_XCORE,		///< XCore 架构
175*9a0e4156SSadaf Ebrahimi	CS_ARCH_M68K,		///< 68K 架构
176*9a0e4156SSadaf Ebrahimi	CS_ARCH_TMS320C64X,	///< TMS320C64x 架构
177*9a0e4156SSadaf Ebrahimi	CS_ARCH_M680X,		///< 680X 架构
178*9a0e4156SSadaf Ebrahimi	CS_ARCH_EVM,		///< Ethereum 架构
179*9a0e4156SSadaf Ebrahimi	CS_ARCH_MAX,
180*9a0e4156SSadaf Ebrahimi	CS_ARCH_ALL = 0xFFFF, // All 架构 - for cs_support()
181*9a0e4156SSadaf Ebrahimi} cs_arch;
182*9a0e4156SSadaf Ebrahimi```
183*9a0e4156SSadaf Ebrahimi
184*9a0e4156SSadaf Ebrahimi</details>
185*9a0e4156SSadaf Ebrahimi
186*9a0e4156SSadaf Ebrahimi> 用法:API中cs_arch参数填入枚举内容,如API中cs_open(cs_arch arch, cs_mode mode, csh *handle);第一个参数填CS_ARCH_X86则支持X86 架构
187*9a0e4156SSadaf Ebrahimi
188*9a0e4156SSadaf Ebrahimi
189*9a0e4156SSadaf Ebrahimi### cs_mode
190*9a0e4156SSadaf Ebrahimi
191*9a0e4156SSadaf Ebrahimi模式选择
192*9a0e4156SSadaf Ebrahimi
193*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
194*9a0e4156SSadaf Ebrahimi
195*9a0e4156SSadaf Ebrahimi```cpp
196*9a0e4156SSadaf Ebrahimienum cs_mode {
197*9a0e4156SSadaf Ebrahimi	CS_MODE_LITTLE_ENDIAN = 0,	             ///< little-endian 模式 (default 模式)
198*9a0e4156SSadaf Ebrahimi	CS_MODE_ARM = 0,	                     ///< 32-bit ARM
199*9a0e4156SSadaf Ebrahimi	CS_MODE_16 = 1 << 1,	                 ///< 16-bit 模式 (X86)
200*9a0e4156SSadaf Ebrahimi	CS_MODE_32 = 1 << 2,	                 ///< 32-bit 模式 (X86)
201*9a0e4156SSadaf Ebrahimi	CS_MODE_64 = 1 << 3,	                 ///< 64-bit 模式 (X86, PPC)
202*9a0e4156SSadaf Ebrahimi	CS_MODE_THUMB = 1 << 4,	                 ///< ARM's Thumb 模式, 包括 Thumb-2
203*9a0e4156SSadaf Ebrahimi	CS_MODE_MCLASS = 1 << 5,	             ///< ARM's Cortex-M 系列
204*9a0e4156SSadaf Ebrahimi	CS_MODE_V8 = 1 << 6,	                 ///< ARMv8 A32解码方式
205*9a0e4156SSadaf Ebrahimi	CS_MODE_MICRO = 1 << 4,                  ///< MicroMips 模式 (MIPS)
206*9a0e4156SSadaf Ebrahimi	CS_MODE_MIPS3 = 1 << 5,                  ///< Mips III ISA
207*9a0e4156SSadaf Ebrahimi	CS_MODE_MIPS32R6 = 1 << 6,               ///< Mips32r6 ISA
208*9a0e4156SSadaf Ebrahimi	CS_MODE_MIPS2 = 1 << 7,                  ///< Mips II ISA
209*9a0e4156SSadaf Ebrahimi	CS_MODE_V9 = 1 << 4,                     ///< SparcV9 模式 (Sparc)
210*9a0e4156SSadaf Ebrahimi	CS_MODE_QPX = 1 << 4,                    ///< Quad Processing eXtensions 模式 (PPC)
211*9a0e4156SSadaf Ebrahimi	CS_MODE_SPE = 1 << 5,                    ///< Signal Processing Engine 模式 (PPC)
212*9a0e4156SSadaf Ebrahimi	CS_MODE_BOOKE = 1 << 6,                  ///< Book-E 模式 (PPC)
213*9a0e4156SSadaf Ebrahimi	CS_MODE_M68K_000 = 1 << 1,               ///< M68K 68000 模式
214*9a0e4156SSadaf Ebrahimi	CS_MODE_M68K_010 = 1 << 2,               ///< M68K 68010 模式
215*9a0e4156SSadaf Ebrahimi	CS_MODE_M68K_020 = 1 << 3,               ///< M68K 68020 模式
216*9a0e4156SSadaf Ebrahimi	CS_MODE_M68K_030 = 1 << 4,               ///< M68K 68030 模式
217*9a0e4156SSadaf Ebrahimi	CS_MODE_M68K_040 = 1 << 5,               ///< M68K 68040 模式
218*9a0e4156SSadaf Ebrahimi	CS_MODE_M68K_060 = 1 << 6,               ///< M68K 68060 模式
219*9a0e4156SSadaf Ebrahimi	CS_MODE_BIG_ENDIAN = 1 << 31,	         ///< big-endian 模式
220*9a0e4156SSadaf Ebrahimi	CS_MODE_MIPS32 = CS_MODE_32,	         ///< Mips32 ISA (Mips)
221*9a0e4156SSadaf Ebrahimi	CS_MODE_MIPS64 = CS_MODE_64,	         ///< Mips64 ISA (Mips)
222*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_6301 = 1 << 1,             ///< M680X Hitachi 6301,6303 模式
223*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_6309 = 1 << 2,             ///< M680X Hitachi 6309 模式
224*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_6800 = 1 << 3,             ///< M680X Motorola 6800,6802 模式
225*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_6801 = 1 << 4,             ///< M680X Motorola 6801,6803 模式
226*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_6805 = 1 << 5,             ///< M680X Motorola/Freescale 6805 模式
227*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_6808 = 1 << 6,             ///< M680X Motorola/Freescale/NXP 68HC08 模式
228*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_6809 = 1 << 7,             ///< M680X Motorola 6809 模式
229*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_6811 = 1 << 8,             ///< M680X Motorola/Freescale/NXP 68HC11 模式
230*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_CPU12 = 1 << 9,            ///< M680X Motorola/Freescale/NXP CPU12
231*9a0e4156SSadaf Ebrahimi					                         ///< 用于 M68HC12/HCS12
232*9a0e4156SSadaf Ebrahimi	CS_MODE_M680X_HCS08 = 1 << 10,           ///< M680X Freescale/NXP HCS08 模式
233*9a0e4156SSadaf Ebrahimi	CS_MODE_BPF_CLASSIC = 0,	             ///< Classic BPF 模式 (默认)
234*9a0e4156SSadaf Ebrahimi	CS_MODE_BPF_EXTENDED = 1 << 0,	         ///< Extended BPF 模式
235*9a0e4156SSadaf Ebrahimi	CS_MODE_RISCV32  = 1 << 0,               ///< RISCV RV32G
236*9a0e4156SSadaf Ebrahimi	CS_MODE_RISCV64  = 1 << 1,               ///< RISCV RV64G
237*9a0e4156SSadaf Ebrahimi	CS_MODE_RISCVC   = 1 << 2,               ///< RISCV 压缩指令模式
238*9a0e4156SSadaf Ebrahimi	CS_MODE_MOS65XX_6502 = 1 << 1,           ///< MOS65XXX MOS 6502
239*9a0e4156SSadaf Ebrahimi	CS_MODE_MOS65XX_65C02 = 1 << 2,          ///< MOS65XXX WDC 65c02
240*9a0e4156SSadaf Ebrahimi	CS_MODE_MOS65XX_W65C02 = 1 << 3,         ///< MOS65XXX WDC W65c02
241*9a0e4156SSadaf Ebrahimi	CS_MODE_MOS65XX_65816 = 1 << 4,          ///< MOS65XXX WDC 65816, 8-bit m/x
242*9a0e4156SSadaf Ebrahimi	CS_MODE_MOS65XX_65816_LONG_M = (1 << 5), ///< MOS65XXX WDC 65816, 16-bit m, 8-bit x
243*9a0e4156SSadaf Ebrahimi	CS_MODE_MOS65XX_65816_LONG_X = (1 << 6), ///< MOS65XXX WDC 65816, 8-bit m, 16-bit x
244*9a0e4156SSadaf Ebrahimi	CS_MODE_MOS65XX_65816_LONG_MX = CS_MODE_MOS65XX_65816_LONG_M | CS_MODE_MOS65XX_65816_LONG_X,
245*9a0e4156SSadaf Ebrahimi} cs_mode;
246*9a0e4156SSadaf Ebrahimi```
247*9a0e4156SSadaf Ebrahimi
248*9a0e4156SSadaf Ebrahimi</details>
249*9a0e4156SSadaf Ebrahimi
250*9a0e4156SSadaf Ebrahimi> 用法:API中cs_mode参数填入枚举内容,如API中cs_open(cs_arch arch, cs_mode mode, csh *handle);第二个参数填CS_MODE_64则支持X64模式
251*9a0e4156SSadaf Ebrahimi
252*9a0e4156SSadaf Ebrahimi
253*9a0e4156SSadaf Ebrahimi### cs_opt_mem
254*9a0e4156SSadaf Ebrahimi
255*9a0e4156SSadaf Ebrahimi内存操作
256*9a0e4156SSadaf Ebrahimi
257*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
258*9a0e4156SSadaf Ebrahimi
259*9a0e4156SSadaf Ebrahimi```cpp
260*9a0e4156SSadaf Ebrahimistruct cs_opt_mem {
261*9a0e4156SSadaf Ebrahimi	cs_malloc_t malloc;
262*9a0e4156SSadaf Ebrahimi	cs_calloc_t calloc;
263*9a0e4156SSadaf Ebrahimi	cs_realloc_t realloc;
264*9a0e4156SSadaf Ebrahimi	cs_free_t free;
265*9a0e4156SSadaf Ebrahimi	cs_vsnprintf_t vsnprintf;
266*9a0e4156SSadaf Ebrahimi} cs_opt_mem;
267*9a0e4156SSadaf Ebrahimi```
268*9a0e4156SSadaf Ebrahimi
269*9a0e4156SSadaf Ebrahimi</details>
270*9a0e4156SSadaf Ebrahimi
271*9a0e4156SSadaf Ebrahimi> 用法:可使用用户自定义的malloc/calloc/realloc/free/vsnprintf()函数,默认使用系统自带malloc(), calloc(), realloc(), free() & vsnprintf()
272*9a0e4156SSadaf Ebrahimi
273*9a0e4156SSadaf Ebrahimi
274*9a0e4156SSadaf Ebrahimi### cs_opt_mnem
275*9a0e4156SSadaf Ebrahimi
276*9a0e4156SSadaf Ebrahimi自定义助记符
277*9a0e4156SSadaf Ebrahimi
278*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
279*9a0e4156SSadaf Ebrahimi
280*9a0e4156SSadaf Ebrahimi```cpp
281*9a0e4156SSadaf Ebrahimistruct cs_opt_mnem {
282*9a0e4156SSadaf Ebrahimi	/// 需要自定义的指令ID
283*9a0e4156SSadaf Ebrahimi	unsigned int id;
284*9a0e4156SSadaf Ebrahimi	/// 自定义的助记符
285*9a0e4156SSadaf Ebrahimi	const char *mnemonic;
286*9a0e4156SSadaf Ebrahimi} cs_opt_mnem;
287*9a0e4156SSadaf Ebrahimi```
288*9a0e4156SSadaf Ebrahimi
289*9a0e4156SSadaf Ebrahimi</details>
290*9a0e4156SSadaf Ebrahimi
291*9a0e4156SSadaf Ebrahimi
292*9a0e4156SSadaf Ebrahimi### cs_opt_type
293*9a0e4156SSadaf Ebrahimi
294*9a0e4156SSadaf Ebrahimi反编译的运行时选项
295*9a0e4156SSadaf Ebrahimi
296*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
297*9a0e4156SSadaf Ebrahimi
298*9a0e4156SSadaf Ebrahimi```cpp
299*9a0e4156SSadaf Ebrahimienum cs_opt_type {
300*9a0e4156SSadaf Ebrahimi	CS_OPT_INVALID = 0, 	///< 无特殊要求
301*9a0e4156SSadaf Ebrahimi	CS_OPT_SYNTAX,	        ///< 汇编输出语法
302*9a0e4156SSadaf Ebrahimi	CS_OPT_DETAIL,	        ///< 将指令结构分解为多个细节
303*9a0e4156SSadaf Ebrahimi	CS_OPT_MODE,	        ///< 运行时改变引擎模式
304*9a0e4156SSadaf Ebrahimi	CS_OPT_MEM,	            ///< 用户定义的动态内存相关函数
305*9a0e4156SSadaf Ebrahimi	CS_OPT_SKIPDATA,        ///< 在反汇编时跳过数据。然后引擎将处于SKIPDATA模式
306*9a0e4156SSadaf Ebrahimi	CS_OPT_SKIPDATA_SETUP,  ///< 为SKIPDATA选项设置用户定义函数
307*9a0e4156SSadaf Ebrahimi	CS_OPT_MNEMONIC,        ///<自定义指令助记符
308*9a0e4156SSadaf Ebrahimi	CS_OPT_UNSIGNED,        ///< 以无符号形式打印立即操作数
309*9a0e4156SSadaf Ebrahimi} cs_opt_type;
310*9a0e4156SSadaf Ebrahimi```
311*9a0e4156SSadaf Ebrahimi
312*9a0e4156SSadaf Ebrahimi</details>
313*9a0e4156SSadaf Ebrahimi
314*9a0e4156SSadaf Ebrahimi> 用法:API cs_option(csh handle, cs_opt_type type, size_t value);中第二个参数
315*9a0e4156SSadaf Ebrahimi
316*9a0e4156SSadaf Ebrahimi
317*9a0e4156SSadaf Ebrahimi### cs_opt_value
318*9a0e4156SSadaf Ebrahimi
319*9a0e4156SSadaf Ebrahimi运行时选项值(与cs_opt_type关联)
320*9a0e4156SSadaf Ebrahimi
321*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
322*9a0e4156SSadaf Ebrahimi
323*9a0e4156SSadaf Ebrahimi```cpp
324*9a0e4156SSadaf Ebrahimienum cs_opt_value {
325*9a0e4156SSadaf Ebrahimi	CS_OPT_OFF = 0,            ///< 关闭一个选项 - 默认为CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
326*9a0e4156SSadaf Ebrahimi	CS_OPT_ON = 3,             ///< 打开一个选项 (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
327*9a0e4156SSadaf Ebrahimi	CS_OPT_SYNTAX_DEFAULT = 0, ///< 默认asm语法 (CS_OPT_SYNTAX).
328*9a0e4156SSadaf Ebrahimi	CS_OPT_SYNTAX_INTEL,       ///< X86 Intel asm语法 - 默认开启 X86 (CS_OPT_SYNTAX).
329*9a0e4156SSadaf Ebrahimi	CS_OPT_SYNTAX_ATT,         ///< X86 ATT 汇编语法 (CS_OPT_SYNTAX).
330*9a0e4156SSadaf Ebrahimi	CS_OPT_SYNTAX_NOREGNAME,   ///< 只打印寄存器名和编号 (CS_OPT_SYNTAX)
331*9a0e4156SSadaf Ebrahimi	CS_OPT_SYNTAX_MASM,        ///< X86 Intel Masm 语法 (CS_OPT_SYNTAX).
332*9a0e4156SSadaf Ebrahimi	CS_OPT_SYNTAX_MOTOROLA,    ///< MOS65XX 用 $ 作为hex头
333*9a0e4156SSadaf Ebrahimi} cs_opt_value;
334*9a0e4156SSadaf Ebrahimi```
335*9a0e4156SSadaf Ebrahimi
336*9a0e4156SSadaf Ebrahimi</details>
337*9a0e4156SSadaf Ebrahimi
338*9a0e4156SSadaf Ebrahimi> 用法:API cs_option(csh handle, cs_opt_type type, size_t value);中第三个参数
339*9a0e4156SSadaf Ebrahimi
340*9a0e4156SSadaf Ebrahimi
341*9a0e4156SSadaf Ebrahimi### cs_op_type
342*9a0e4156SSadaf Ebrahimi
343*9a0e4156SSadaf Ebrahimi通用指令操作数类型,在所有架构中保持一致
344*9a0e4156SSadaf Ebrahimi
345*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
346*9a0e4156SSadaf Ebrahimi
347*9a0e4156SSadaf Ebrahimi```cpp
348*9a0e4156SSadaf Ebrahimienum cs_op_type {
349*9a0e4156SSadaf Ebrahimi	CS_OP_INVALID = 0,  ///< 未初始化/无效的操作数
350*9a0e4156SSadaf Ebrahimi	CS_OP_REG,          ///< 寄存器操作数
351*9a0e4156SSadaf Ebrahimi	CS_OP_IMM,          ///< 立即操作数
352*9a0e4156SSadaf Ebrahimi	CS_OP_MEM,          ///< 内存操作数
353*9a0e4156SSadaf Ebrahimi	CS_OP_FP,           ///< 浮点数
354*9a0e4156SSadaf Ebrahimi} cs_op_type;
355*9a0e4156SSadaf Ebrahimi```
356*9a0e4156SSadaf Ebrahimi
357*9a0e4156SSadaf Ebrahimi</details>
358*9a0e4156SSadaf Ebrahimi
359*9a0e4156SSadaf Ebrahimi> 目前开放的API中未调用
360*9a0e4156SSadaf Ebrahimi
361*9a0e4156SSadaf Ebrahimi
362*9a0e4156SSadaf Ebrahimi### cs_ac_type
363*9a0e4156SSadaf Ebrahimi
364*9a0e4156SSadaf Ebrahimi通用指令操作数访问类型,在所有架构中保持一致
365*9a0e4156SSadaf Ebrahimi可以组合访问类型,例如:CS_AC_READ | CS_AC_WRITE
366*9a0e4156SSadaf Ebrahimi
367*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
368*9a0e4156SSadaf Ebrahimi
369*9a0e4156SSadaf Ebrahimi```cpp
370*9a0e4156SSadaf Ebrahimienum cs_ac_type {
371*9a0e4156SSadaf Ebrahimi	CS_AC_INVALID = 0,        ///< 未初始化/无效的访问类型
372*9a0e4156SSadaf Ebrahimi	CS_AC_READ    = 1 << 0,   ///< 操作数从内存或寄存器中读取
373*9a0e4156SSadaf Ebrahimi	CS_AC_WRITE   = 1 << 1,   ///< 操作数从内存或寄存器中写入
374*9a0e4156SSadaf Ebrahimi} cs_ac_type;
375*9a0e4156SSadaf Ebrahimi```
376*9a0e4156SSadaf Ebrahimi
377*9a0e4156SSadaf Ebrahimi</details>
378*9a0e4156SSadaf Ebrahimi
379*9a0e4156SSadaf Ebrahimi> 目前开放的API中未调用
380*9a0e4156SSadaf Ebrahimi
381*9a0e4156SSadaf Ebrahimi
382*9a0e4156SSadaf Ebrahimi### cs_group_type
383*9a0e4156SSadaf Ebrahimi
384*9a0e4156SSadaf Ebrahimi公共指令组,在所有架构中保持一致
385*9a0e4156SSadaf Ebrahimi
386*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
387*9a0e4156SSadaf Ebrahimi
388*9a0e4156SSadaf Ebrahimi```cpp
389*9a0e4156SSadaf Ebrahimics_group_type {
390*9a0e4156SSadaf Ebrahimi	CS_GRP_INVALID = 0,  ///< 未初始化/无效指令组
391*9a0e4156SSadaf Ebrahimi	CS_GRP_JUMP,    ///< 所有跳转指令(条件跳转+直接跳转+间接跳转)
392*9a0e4156SSadaf Ebrahimi	CS_GRP_CALL,    ///< 所有调用指令
393*9a0e4156SSadaf Ebrahimi	CS_GRP_RET,     ///< 所有返回指令
394*9a0e4156SSadaf Ebrahimi	CS_GRP_INT,     ///< 所有中断指令(int+syscall)
395*9a0e4156SSadaf Ebrahimi	CS_GRP_IRET,    ///< 所有中断返回指令
396*9a0e4156SSadaf Ebrahimi	CS_GRP_PRIVILEGE,    ///< 所有特权指令
397*9a0e4156SSadaf Ebrahimi	CS_GRP_BRANCH_RELATIVE, ///< 所有相关分支指令
398*9a0e4156SSadaf Ebrahimi} cs_group_type;
399*9a0e4156SSadaf Ebrahimi```
400*9a0e4156SSadaf Ebrahimi
401*9a0e4156SSadaf Ebrahimi</details>
402*9a0e4156SSadaf Ebrahimi
403*9a0e4156SSadaf Ebrahimi> 目前开放的API中未调用
404*9a0e4156SSadaf Ebrahimi
405*9a0e4156SSadaf Ebrahimi
406*9a0e4156SSadaf Ebrahimi### cs_opt_skipdata
407*9a0e4156SSadaf Ebrahimi
408*9a0e4156SSadaf Ebrahimi用户自定义设置SKIPDATA选项
409*9a0e4156SSadaf Ebrahimi
410*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
411*9a0e4156SSadaf Ebrahimi
412*9a0e4156SSadaf Ebrahimi```cpp
413*9a0e4156SSadaf Ebrahimistruct cs_opt_skipdata {
414*9a0e4156SSadaf Ebrahimi	/// Capstone认为要跳过的数据是特殊的“指令”
415*9a0e4156SSadaf Ebrahimi	/// 用户可以在这里指定该指令的“助记符”字符串
416*9a0e4156SSadaf Ebrahimi	/// 默认情况下(@mnemonic为NULL), Capstone使用“.byte”
417*9a0e4156SSadaf Ebrahimi	const char *mnemonic;
418*9a0e4156SSadaf Ebrahimi
419*9a0e4156SSadaf Ebrahimi	/// 用户定义的回调函数,当Capstone命中数据时调用
420*9a0e4156SSadaf Ebrahimi	/// 如果这个回调返回的值是正数(>0),Capstone将跳过这个字节数并继续。如果回调返回0,Capstone将停止反汇编并立即从cs_disasm()返回
421*9a0e4156SSadaf Ebrahimi	/// 注意:如果这个回调指针为空,Capstone会根据架构跳过一些字节,如下所示:
422*9a0e4156SSadaf Ebrahimi	/// Arm:     2 bytes (Thumb mode) or 4 bytes.
423*9a0e4156SSadaf Ebrahimi	/// Arm64:   4 bytes.
424*9a0e4156SSadaf Ebrahimi	/// Mips:    4 bytes.
425*9a0e4156SSadaf Ebrahimi	/// M680x:   1 byte.
426*9a0e4156SSadaf Ebrahimi	/// PowerPC: 4 bytes.
427*9a0e4156SSadaf Ebrahimi	/// Sparc:   4 bytes.
428*9a0e4156SSadaf Ebrahimi	/// SystemZ: 2 bytes.
429*9a0e4156SSadaf Ebrahimi	/// X86:     1 bytes.
430*9a0e4156SSadaf Ebrahimi	/// XCore:   2 bytes.
431*9a0e4156SSadaf Ebrahimi	/// EVM:     1 bytes.
432*9a0e4156SSadaf Ebrahimi	/// RISCV:   4 bytes.
433*9a0e4156SSadaf Ebrahimi	/// WASM:    1 bytes.
434*9a0e4156SSadaf Ebrahimi	/// MOS65XX: 1 bytes.
435*9a0e4156SSadaf Ebrahimi	/// BPF:     8 bytes.
436*9a0e4156SSadaf Ebrahimi	cs_skipdata_cb_t callback; 	// 默认值为 NULL
437*9a0e4156SSadaf Ebrahimi
438*9a0e4156SSadaf Ebrahimi	/// 用户自定义数据将被传递给@callback函数指针
439*9a0e4156SSadaf Ebrahimi	void *user_data;
440*9a0e4156SSadaf Ebrahimi} cs_opt_skipdata;
441*9a0e4156SSadaf Ebrahimi```
442*9a0e4156SSadaf Ebrahimi
443*9a0e4156SSadaf Ebrahimi</details>
444*9a0e4156SSadaf Ebrahimi
445*9a0e4156SSadaf Ebrahimi> 目前开放的API中未调用
446*9a0e4156SSadaf Ebrahimi
447*9a0e4156SSadaf Ebrahimi
448*9a0e4156SSadaf Ebrahimi### cs_detail
449*9a0e4156SSadaf Ebrahimi
450*9a0e4156SSadaf Ebrahimi注意:只有当CS_OPT_DETAIL = CS_OPT_ON时,cs_detail中的所有信息才可用
451*9a0e4156SSadaf Ebrahimi
452*9a0e4156SSadaf Ebrahimiarch/ARCH/ARCHDisassembler.c的ARCH_getInstruction中初始化为memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH))
453*9a0e4156SSadaf Ebrahimi
454*9a0e4156SSadaf Ebrahimi如果cs_detail发生了变化,特别是在union之后添加了字段,那么相应地更新arch/ arch/ archdisassembly.c
455*9a0e4156SSadaf Ebrahimi
456*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
457*9a0e4156SSadaf Ebrahimi
458*9a0e4156SSadaf Ebrahimi```cpp
459*9a0e4156SSadaf Ebrahimistruct cs_detail {
460*9a0e4156SSadaf Ebrahimi	uint16_t regs_read[16]; ///< 这个参数读取隐式寄存器列表
461*9a0e4156SSadaf Ebrahimi	uint8_t regs_read_count; ///< 这个参数读取隐式寄存器计数
462*9a0e4156SSadaf Ebrahimi
463*9a0e4156SSadaf Ebrahimi	uint16_t regs_write[20]; ///< 这个参数修改隐式寄存器列表
464*9a0e4156SSadaf Ebrahimi	uint8_t regs_write_count; ///< 这个参数修改隐式寄存器计数
465*9a0e4156SSadaf Ebrahimi
466*9a0e4156SSadaf Ebrahimi	uint8_t groups[8]; ///< 此指令所属的指令组的列表
467*9a0e4156SSadaf Ebrahimi	uint8_t groups_count; ///< 此指令所属的组的数
468*9a0e4156SSadaf Ebrahimi
469*9a0e4156SSadaf Ebrahimi	/// 特定于体系结构的信息
470*9a0e4156SSadaf Ebrahimi	union {
471*9a0e4156SSadaf Ebrahimi		cs_x86 x86;     ///< X86 架构, 包括 16-bit, 32-bit & 64-bit 模式
472*9a0e4156SSadaf Ebrahimi		cs_arm64 arm64; ///< ARM64 架构 (aka AArch64)
473*9a0e4156SSadaf Ebrahimi		cs_arm arm;     ///< ARM 架构 (包括 Thumb/Thumb2)
474*9a0e4156SSadaf Ebrahimi		cs_m68k m68k;   ///< M68K 架构
475*9a0e4156SSadaf Ebrahimi		cs_mips mips;   ///< MIPS 架构
476*9a0e4156SSadaf Ebrahimi		cs_ppc ppc;	    ///< PowerPC 架构
477*9a0e4156SSadaf Ebrahimi		cs_sparc sparc; ///< Sparc 架构
478*9a0e4156SSadaf Ebrahimi		cs_sysz sysz;   ///< SystemZ 架构
479*9a0e4156SSadaf Ebrahimi		cs_xcore xcore; ///< XCore 架构
480*9a0e4156SSadaf Ebrahimi		cs_tms320c64x tms320c64x;  ///< TMS320C64x 架构
481*9a0e4156SSadaf Ebrahimi		cs_m680x m680x; ///< M680X 架构
482*9a0e4156SSadaf Ebrahimi		cs_evm evm;	    ///< Ethereum 架构
483*9a0e4156SSadaf Ebrahimi		cs_mos65xx mos65xx;	///< MOS65XX 架构 (包含 MOS6502)
484*9a0e4156SSadaf Ebrahimi		cs_wasm wasm;	///< Web Assembly 架构
485*9a0e4156SSadaf Ebrahimi		cs_bpf bpf;	///< Berkeley Packet Filter 架构 (包含 eBPF)
486*9a0e4156SSadaf Ebrahimi		cs_riscv riscv; ///< RISCV 架构
487*9a0e4156SSadaf Ebrahimi	};
488*9a0e4156SSadaf Ebrahimi} cs_detail;
489*9a0e4156SSadaf Ebrahimi```
490*9a0e4156SSadaf Ebrahimi
491*9a0e4156SSadaf Ebrahimi</details>
492*9a0e4156SSadaf Ebrahimi
493*9a0e4156SSadaf Ebrahimi
494*9a0e4156SSadaf Ebrahimi### cs_insn
495*9a0e4156SSadaf Ebrahimi
496*9a0e4156SSadaf Ebrahimi指令的详细信息
497*9a0e4156SSadaf Ebrahimi
498*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
499*9a0e4156SSadaf Ebrahimi
500*9a0e4156SSadaf Ebrahimi```cpp
501*9a0e4156SSadaf Ebrahimistruct cs_insn {
502*9a0e4156SSadaf Ebrahimi	/// 指令ID(基本上是一个用于指令助记符的数字ID)
503*9a0e4156SSadaf Ebrahimi	/// 应在相应架构的头文件中查找'[ARCH]_insn' enum中的指令id,如ARM.h中的'arm_insn'代表ARM, X86.h中的'x86_insn'代表X86等…
504*9a0e4156SSadaf Ebrahimi	/// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息
505*9a0e4156SSadaf Ebrahimi	/// 注意:在Skipdata模式下,这个id字段的“data”指令为0
506*9a0e4156SSadaf Ebrahimi	unsigned int id;
507*9a0e4156SSadaf Ebrahimi
508*9a0e4156SSadaf Ebrahimi	/// 指令地址 (EIP)
509*9a0e4156SSadaf Ebrahimi	/// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息
510*9a0e4156SSadaf Ebrahimi	uint64_t address;
511*9a0e4156SSadaf Ebrahimi
512*9a0e4156SSadaf Ebrahimi	/// 指令长度
513*9a0e4156SSadaf Ebrahimi	/// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息
514*9a0e4156SSadaf Ebrahimi	uint16_t size;
515*9a0e4156SSadaf Ebrahimi
516*9a0e4156SSadaf Ebrahimi	/// 此指令的机器码,其字节数由上面的@size表示
517*9a0e4156SSadaf Ebrahimi	/// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息
518*9a0e4156SSadaf Ebrahimi	uint8_t bytes[24];
519*9a0e4156SSadaf Ebrahimi
520*9a0e4156SSadaf Ebrahimi	/// 指令的Ascii文本助记符
521*9a0e4156SSadaf Ebrahimi	/// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息
522*9a0e4156SSadaf Ebrahimi	char mnemonic[CS_MNEMONIC_SIZE];
523*9a0e4156SSadaf Ebrahimi
524*9a0e4156SSadaf Ebrahimi	/// 指令操作数的Ascii文本
525*9a0e4156SSadaf Ebrahimi	/// 即使在CS_OPT_DETAIL = CS_OPT_OFF时也可以使用此信息
526*9a0e4156SSadaf Ebrahimi	char op_str[160];
527*9a0e4156SSadaf Ebrahimi
528*9a0e4156SSadaf Ebrahimi	/// cs_detail指针
529*9a0e4156SSadaf Ebrahimi	/// 注意:只有同时满足以下两个要求时,detail指针才有效:
530*9a0e4156SSadaf Ebrahimi	/// (1) CS_OP_DETAIL = CS_OPT_ON
531*9a0e4156SSadaf Ebrahimi	/// (2) 引擎未处于Skipdata模式(CS_OP_SKIPDATA选项设置为CS_OPT_ON)
532*9a0e4156SSadaf Ebrahimi	///
533*9a0e4156SSadaf Ebrahimi	/// 注意2:当处于Skipdata模式或detail模式关闭时,即使这个指针不是NULL,它的内容仍然是不相关的。
534*9a0e4156SSadaf Ebrahimi	cs_detail *detail;
535*9a0e4156SSadaf Ebrahimi} cs_insn;
536*9a0e4156SSadaf Ebrahimi```
537*9a0e4156SSadaf Ebrahimi
538*9a0e4156SSadaf Ebrahimi</details>
539*9a0e4156SSadaf Ebrahimi
540*9a0e4156SSadaf Ebrahimi
541*9a0e4156SSadaf Ebrahimi### cs_err
542*9a0e4156SSadaf Ebrahimi
543*9a0e4156SSadaf EbrahimiCapstone API遇到的各类型的错误时cs_errno()的返回值
544*9a0e4156SSadaf Ebrahimi
545*9a0e4156SSadaf Ebrahimi<details><summary> Code </summary>
546*9a0e4156SSadaf Ebrahimi
547*9a0e4156SSadaf Ebrahimi```cpp
548*9a0e4156SSadaf Ebrahimitypedef enum cs_err {
549*9a0e4156SSadaf Ebrahimi	CS_ERR_OK = 0,    ///< 无错误
550*9a0e4156SSadaf Ebrahimi	CS_ERR_MEM,       ///< 内存不足: cs_open(), cs_disasm(), cs_disasm_iter()
551*9a0e4156SSadaf Ebrahimi	CS_ERR_ARCH,      ///< 不支持的架构: cs_open()
552*9a0e4156SSadaf Ebrahimi	CS_ERR_HANDLE,    ///<句柄不可用: cs_op_count(), cs_op_index()
553*9a0e4156SSadaf Ebrahimi	CS_ERR_CSH,       ///< csh参数不可用: cs_close(), cs_errno(), cs_option()
554*9a0e4156SSadaf Ebrahimi	CS_ERR_MODE,      ///< 无效的或不支持的模式: cs_open()
555*9a0e4156SSadaf Ebrahimi	CS_ERR_OPTION,    ///< 无效的或不支持的选项: cs_option()
556*9a0e4156SSadaf Ebrahimi	CS_ERR_DETAIL,    ///< 信息不可用,因为detail选项是关闭的
557*9a0e4156SSadaf Ebrahimi	CS_ERR_MEMSETUP,  ///< 动态内存管理未初始化(见 CS_OPT_MEM)
558*9a0e4156SSadaf Ebrahimi	CS_ERR_VERSION,   ///< 不支持版本 (bindings)
559*9a0e4156SSadaf Ebrahimi	CS_ERR_DIET,      ///< 在“diet”引擎中访问不相关的数据
560*9a0e4156SSadaf Ebrahimi	CS_ERR_SKIPDATA,  ///< 在SKIPDATA模式下访问与“数据”指令无关的数据
561*9a0e4156SSadaf Ebrahimi	CS_ERR_X86_ATT,   ///< X86 AT&T 语法不支持(在编译时退出)
562*9a0e4156SSadaf Ebrahimi	CS_ERR_X86_INTEL, ///< X86 Intel 语法不支持(在编译时退出)
563*9a0e4156SSadaf Ebrahimi	CS_ERR_X86_MASM,  ///< X86 Intel 语法不支持(在编译时退出)
564*9a0e4156SSadaf Ebrahimi} cs_err;
565*9a0e4156SSadaf Ebrahimi```
566*9a0e4156SSadaf Ebrahimi
567*9a0e4156SSadaf Ebrahimi</details>
568*9a0e4156SSadaf Ebrahimi
569*9a0e4156SSadaf Ebrahimi
570*9a0e4156SSadaf Ebrahimi## 0x2 API
571*9a0e4156SSadaf Ebrahimi
572*9a0e4156SSadaf Ebrahimi### cs_version
573*9a0e4156SSadaf Ebrahimi
574*9a0e4156SSadaf Ebrahimi`unsigned int CAPSTONE_API cs_version(int *major, int *minor);`
575*9a0e4156SSadaf Ebrahimi
576*9a0e4156SSadaf Ebrahimi用来输出capstone版本号
577*9a0e4156SSadaf Ebrahimi
578*9a0e4156SSadaf Ebrahimi```
579*9a0e4156SSadaf Ebrahimimajor: API主版本
580*9a0e4156SSadaf Ebrahimiminor: API次版本
581*9a0e4156SSadaf Ebrahimireturn: 返回主次版本的16进制,如4.0版本返回 0x0400
582*9a0e4156SSadaf Ebrahimi```
583*9a0e4156SSadaf Ebrahimi
584*9a0e4156SSadaf Ebrahimi该版本定义于cs.c中,编译后不可更改,不接受自定义版本
585*9a0e4156SSadaf Ebrahimi
586*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/7.jpg)
587*9a0e4156SSadaf Ebrahimi
588*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/8.jpg)
589*9a0e4156SSadaf Ebrahimi
590*9a0e4156SSadaf Ebrahimi
591*9a0e4156SSadaf Ebrahimi<details><summary> 示例1 </summary>
592*9a0e4156SSadaf Ebrahimi
593*9a0e4156SSadaf Ebrahimi```c
594*9a0e4156SSadaf Ebrahimi#include <stdio.h>
595*9a0e4156SSadaf Ebrahimi#include <stdlib.h>
596*9a0e4156SSadaf Ebrahimi
597*9a0e4156SSadaf Ebrahimi#include "platform.h"
598*9a0e4156SSadaf Ebrahimi#include "capstone.h"
599*9a0e4156SSadaf Ebrahimi
600*9a0e4156SSadaf Ebrahimistatic int test()
601*9a0e4156SSadaf Ebrahimi{
602*9a0e4156SSadaf Ebrahimi	return cs_version(NULL, NULL);
603*9a0e4156SSadaf Ebrahimi}
604*9a0e4156SSadaf Ebrahimi
605*9a0e4156SSadaf Ebrahimiint main()
606*9a0e4156SSadaf Ebrahimi{
607*9a0e4156SSadaf Ebrahimi	int version = test();
608*9a0e4156SSadaf Ebrahimi	printf("%X", version);
609*9a0e4156SSadaf Ebrahimi	return 0;
610*9a0e4156SSadaf Ebrahimi}
611*9a0e4156SSadaf Ebrahimi```
612*9a0e4156SSadaf Ebrahimi
613*9a0e4156SSadaf Ebrahimi</details>
614*9a0e4156SSadaf Ebrahimi
615*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/9.jpg)
616*9a0e4156SSadaf Ebrahimi
617*9a0e4156SSadaf Ebrahimi
618*9a0e4156SSadaf Ebrahimi<details><summary> 示例2,强行修改版本 </summary>
619*9a0e4156SSadaf Ebrahimi
620*9a0e4156SSadaf Ebrahimi```cpp
621*9a0e4156SSadaf Ebrahimi#include <stdio.h>
622*9a0e4156SSadaf Ebrahimi#include <stdlib.h>
623*9a0e4156SSadaf Ebrahimi
624*9a0e4156SSadaf Ebrahimi#include "platform.h"
625*9a0e4156SSadaf Ebrahimi#include "capstone.h"
626*9a0e4156SSadaf Ebrahimi
627*9a0e4156SSadaf Ebrahimistatic int test()
628*9a0e4156SSadaf Ebrahimi{
629*9a0e4156SSadaf Ebrahimi	int ma[] = { 5 };
630*9a0e4156SSadaf Ebrahimi	int mi[] = { 6 };
631*9a0e4156SSadaf Ebrahimi
632*9a0e4156SSadaf Ebrahimi	return cs_version(ma, mi);
633*9a0e4156SSadaf Ebrahimi}
634*9a0e4156SSadaf Ebrahimi
635*9a0e4156SSadaf Ebrahimiint main()
636*9a0e4156SSadaf Ebrahimi{
637*9a0e4156SSadaf Ebrahimi	int version = test();
638*9a0e4156SSadaf Ebrahimi	printf("%X", version);
639*9a0e4156SSadaf Ebrahimi	return 0;
640*9a0e4156SSadaf Ebrahimi}
641*9a0e4156SSadaf Ebrahimi```
642*9a0e4156SSadaf Ebrahimi
643*9a0e4156SSadaf Ebrahimi</details>
644*9a0e4156SSadaf Ebrahimi
645*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/10.jpg)
646*9a0e4156SSadaf Ebrahimi
647*9a0e4156SSadaf Ebrahimi可见并不能改变
648*9a0e4156SSadaf Ebrahimi
649*9a0e4156SSadaf Ebrahimi### cs_support
650*9a0e4156SSadaf Ebrahimi
651*9a0e4156SSadaf Ebrahimi`bool CAPSTONE_API cs_support(int query);`
652*9a0e4156SSadaf Ebrahimi
653*9a0e4156SSadaf Ebrahimi用来检查capstone库是否支持参数输入的架构或处于某编译选项
654*9a0e4156SSadaf Ebrahimi
655*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
656*9a0e4156SSadaf Ebrahimi
657*9a0e4156SSadaf Ebrahimi
658*9a0e4156SSadaf Ebrahimi```cpp
659*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_support(int query)
660*9a0e4156SSadaf Ebrahimi{
661*9a0e4156SSadaf Ebrahimi	if (query == CS_ARCH_ALL)
662*9a0e4156SSadaf Ebrahimi		return all_arch == ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM64) |
663*9a0e4156SSadaf Ebrahimi				(1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
664*9a0e4156SSadaf Ebrahimi				(1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) |
665*9a0e4156SSadaf Ebrahimi				(1 << CS_ARCH_SYSZ) | (1 << CS_ARCH_XCORE) |
666*9a0e4156SSadaf Ebrahimi				(1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
667*9a0e4156SSadaf Ebrahimi				(1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM));
668*9a0e4156SSadaf Ebrahimi
669*9a0e4156SSadaf Ebrahimi	if ((unsigned int)query < CS_ARCH_MAX)
670*9a0e4156SSadaf Ebrahimi		return all_arch & (1 << query);
671*9a0e4156SSadaf Ebrahimi
672*9a0e4156SSadaf Ebrahimi	if (query == CS_SUPPORT_DIET) {
673*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET
674*9a0e4156SSadaf Ebrahimi		return true;
675*9a0e4156SSadaf Ebrahimi#else
676*9a0e4156SSadaf Ebrahimi		return false;
677*9a0e4156SSadaf Ebrahimi#endif
678*9a0e4156SSadaf Ebrahimi	}
679*9a0e4156SSadaf Ebrahimi
680*9a0e4156SSadaf Ebrahimi	if (query == CS_SUPPORT_X86_REDUCE) {
681*9a0e4156SSadaf Ebrahimi#if defined(CAPSTONE_HAS_X86) && defined(CAPSTONE_X86_REDUCE)
682*9a0e4156SSadaf Ebrahimi		return true;
683*9a0e4156SSadaf Ebrahimi#else
684*9a0e4156SSadaf Ebrahimi		return false;
685*9a0e4156SSadaf Ebrahimi#endif
686*9a0e4156SSadaf Ebrahimi	}
687*9a0e4156SSadaf Ebrahimi
688*9a0e4156SSadaf Ebrahimi	// unsupported query
689*9a0e4156SSadaf Ebrahimi	return false;
690*9a0e4156SSadaf Ebrahimi}
691*9a0e4156SSadaf Ebrahimi```
692*9a0e4156SSadaf Ebrahimi
693*9a0e4156SSadaf Ebrahimi</details>
694*9a0e4156SSadaf Ebrahimi
695*9a0e4156SSadaf Ebrahimi示例1(CS_ARCH_ALL,检查是否支持所有架构)
696*9a0e4156SSadaf Ebrahimi
697*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/12.jpg)
698*9a0e4156SSadaf Ebrahimi
699*9a0e4156SSadaf Ebrahimi示例2(CS_ARCH_*,检查是否支持指定架构)
700*9a0e4156SSadaf Ebrahimi
701*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/13.jpg)
702*9a0e4156SSadaf Ebrahimi
703*9a0e4156SSadaf Ebrahimi示例3(检查是否处于DIET编译模式):
704*9a0e4156SSadaf Ebrahimi
705*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/14.jpg)
706*9a0e4156SSadaf Ebrahimi
707*9a0e4156SSadaf Ebrahimi示例4(检查是否处于X86_REDUCE编译模式)
708*9a0e4156SSadaf Ebrahimi
709*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/15.jpg)
710*9a0e4156SSadaf Ebrahimi
711*9a0e4156SSadaf Ebrahimi
712*9a0e4156SSadaf Ebrahimi### cs_malloc_t
713*9a0e4156SSadaf Ebrahimi
714*9a0e4156SSadaf Ebrahimi`void* (CAPSTONE_API *cs_malloc_t)(size_t size);`
715*9a0e4156SSadaf Ebrahimi
716*9a0e4156SSadaf Ebrahimics的动态内存分配,用于
717*9a0e4156SSadaf Ebrahimi
718*9a0e4156SSadaf Ebrahimi```cpp
719*9a0e4156SSadaf Ebrahimistruct cs_opt_mem {
720*9a0e4156SSadaf Ebrahimi	cs_malloc_t malloc;
721*9a0e4156SSadaf Ebrahimi	cs_calloc_t calloc;
722*9a0e4156SSadaf Ebrahimi	cs_realloc_t realloc;
723*9a0e4156SSadaf Ebrahimi	cs_free_t free;
724*9a0e4156SSadaf Ebrahimi	cs_vsnprintf_t vsnprintf;
725*9a0e4156SSadaf Ebrahimi} cs_opt_mem;
726*9a0e4156SSadaf Ebrahimi```
727*9a0e4156SSadaf Ebrahimi
728*9a0e4156SSadaf Ebrahimi在用户模式下,cs_mem_malloc默认使用系统malloc
729*9a0e4156SSadaf Ebrahimi
730*9a0e4156SSadaf EbrahimiWindows driver模式下,`cs_malloc_t cs_mem_malloc = cs_winkernel_malloc;`
731*9a0e4156SSadaf Ebrahimi
732*9a0e4156SSadaf Ebrahimics_winkernel_malloc定义于\capstone-4.0.1\windows\winkernel_mm.c,
733*9a0e4156SSadaf Ebrahimi
734*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
735*9a0e4156SSadaf Ebrahimi
736*9a0e4156SSadaf Ebrahimi```cpp
737*9a0e4156SSadaf Ebrahimivoid * CAPSTONE_API cs_winkernel_malloc(size_t size)
738*9a0e4156SSadaf Ebrahimi{
739*9a0e4156SSadaf Ebrahimi	// 长度不能分配为0
740*9a0e4156SSadaf Ebrahimi	NT_ASSERT(size);
741*9a0e4156SSadaf Ebrahimi
742*9a0e4156SSadaf Ebrahimi	// FP; NonPagedPool用于支持 Windows 7
743*9a0e4156SSadaf Ebrahimi#pragma prefast(suppress : 30030)		// 分配可执行的POOL_TYPE内存
744*9a0e4156SSadaf Ebrahimi	size_t number_of_bytes = 0;
745*9a0e4156SSadaf Ebrahimi	CS_WINKERNEL_MEMBLOCK *block = NULL;
746*9a0e4156SSadaf Ebrahimi	// 特定的值能造成溢出
747*9a0e4156SSadaf Ebrahimi	// 如果value中的和超出或低于类型容量,函数将返回NULL。
748*9a0e4156SSadaf Ebrahimi	if (!NT_SUCCESS(RtlSizeTAdd(size, sizeof(CS_WINKERNEL_MEMBLOCK), &number_of_bytes))) {
749*9a0e4156SSadaf Ebrahimi		return NULL;
750*9a0e4156SSadaf Ebrahimi	}
751*9a0e4156SSadaf Ebrahimi	block = (CS_WINKERNEL_MEMBLOCK *)ExAllocatePoolWithTag(
752*9a0e4156SSadaf Ebrahimi			NonPagedPool, number_of_bytes, CS_WINKERNEL_POOL_TAG);
753*9a0e4156SSadaf Ebrahimi	if (!block) {
754*9a0e4156SSadaf Ebrahimi		return NULL;
755*9a0e4156SSadaf Ebrahimi	}
756*9a0e4156SSadaf Ebrahimi	block->size = size;
757*9a0e4156SSadaf Ebrahimi
758*9a0e4156SSadaf Ebrahimi	return block->data;
759*9a0e4156SSadaf Ebrahimi}
760*9a0e4156SSadaf Ebrahimi```
761*9a0e4156SSadaf Ebrahimi
762*9a0e4156SSadaf Ebrahimi</details>
763*9a0e4156SSadaf Ebrahimi
764*9a0e4156SSadaf Ebrahimi> OSX kernel模式下,`cs_malloc_t cs_mem_malloc = kern_os_malloc;`,这里暂且不探讨。
765*9a0e4156SSadaf Ebrahimi
766*9a0e4156SSadaf Ebrahimi
767*9a0e4156SSadaf Ebrahimi### cs_calloc_t
768*9a0e4156SSadaf Ebrahimi
769*9a0e4156SSadaf Ebrahimi`void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size);`
770*9a0e4156SSadaf Ebrahimi
771*9a0e4156SSadaf Ebrahimics申请内存并初始化
772*9a0e4156SSadaf Ebrahimi
773*9a0e4156SSadaf Ebrahimi用于`struct cs_opt_mem`,定义于cs.c
774*9a0e4156SSadaf Ebrahimi
775*9a0e4156SSadaf Ebrahimi用户模式: `cs_calloc_t cs_mem_calloc = calloc;`,使用系统calloc
776*9a0e4156SSadaf Ebrahimi
777*9a0e4156SSadaf EbrahimiWindows driver模式: `cs_calloc_t cs_mem_calloc = cs_winkernel_calloc;`
778*9a0e4156SSadaf Ebrahimi
779*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
780*9a0e4156SSadaf Ebrahimi
781*9a0e4156SSadaf Ebrahimi```cpp
782*9a0e4156SSadaf Ebrahimivoid * CAPSTONE_API cs_winkernel_calloc(size_t n, size_t size)
783*9a0e4156SSadaf Ebrahimi{
784*9a0e4156SSadaf Ebrahimi	size_t total = n * size;
785*9a0e4156SSadaf Ebrahimi
786*9a0e4156SSadaf Ebrahimi	void *new_ptr = cs_winkernel_malloc(total);
787*9a0e4156SSadaf Ebrahimi	if (!new_ptr) {
788*9a0e4156SSadaf Ebrahimi		return NULL;
789*9a0e4156SSadaf Ebrahimi	}
790*9a0e4156SSadaf Ebrahimi
791*9a0e4156SSadaf Ebrahimi	return RtlFillMemory(new_ptr, total, 0);
792*9a0e4156SSadaf Ebrahimi}
793*9a0e4156SSadaf Ebrahimi```
794*9a0e4156SSadaf Ebrahimi
795*9a0e4156SSadaf Ebrahimi</details>
796*9a0e4156SSadaf Ebrahimi
797*9a0e4156SSadaf Ebrahimi> OSX kernel模式: `cs_calloc_t cs_mem_calloc = cs_kern_os_calloc;` 直接调用kern_os_malloc
798*9a0e4156SSadaf Ebrahimi
799*9a0e4156SSadaf Ebrahimi
800*9a0e4156SSadaf Ebrahimi### cs_realloc_t
801*9a0e4156SSadaf Ebrahimi
802*9a0e4156SSadaf Ebrahimi`void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size);`
803*9a0e4156SSadaf Ebrahimi
804*9a0e4156SSadaf Ebrahimics重新分配内存
805*9a0e4156SSadaf Ebrahimi
806*9a0e4156SSadaf Ebrahimi用于`struct cs_opt_mem`,定义于cs.c
807*9a0e4156SSadaf Ebrahimi
808*9a0e4156SSadaf Ebrahimi用户模式: `cs_realloc_t cs_mem_realloc = realloc;`,调用系统realloc
809*9a0e4156SSadaf Ebrahimi
810*9a0e4156SSadaf EbrahimiWindows driver模式: `cs_realloc_t cs_mem_realloc = cs_winkernel_realloc;`
811*9a0e4156SSadaf Ebrahimi
812*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
813*9a0e4156SSadaf Ebrahimi
814*9a0e4156SSadaf Ebrahimi```cpp
815*9a0e4156SSadaf Ebrahimivoid * CAPSTONE_API cs_winkernel_realloc(void *ptr, size_t size)
816*9a0e4156SSadaf Ebrahimi{
817*9a0e4156SSadaf Ebrahimi	void *new_ptr = NULL;
818*9a0e4156SSadaf Ebrahimi	size_t current_size = 0;
819*9a0e4156SSadaf Ebrahimi	size_t smaller_size = 0;
820*9a0e4156SSadaf Ebrahimi
821*9a0e4156SSadaf Ebrahimi	if (!ptr) {
822*9a0e4156SSadaf Ebrahimi		return cs_winkernel_malloc(size);
823*9a0e4156SSadaf Ebrahimi	}
824*9a0e4156SSadaf Ebrahimi
825*9a0e4156SSadaf Ebrahimi	new_ptr = cs_winkernel_malloc(size);
826*9a0e4156SSadaf Ebrahimi	if (!new_ptr) {
827*9a0e4156SSadaf Ebrahimi		return NULL;
828*9a0e4156SSadaf Ebrahimi	}
829*9a0e4156SSadaf Ebrahimi
830*9a0e4156SSadaf Ebrahimi	current_size = CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data)->size;
831*9a0e4156SSadaf Ebrahimi	smaller_size = (current_size < size) ? current_size : size;
832*9a0e4156SSadaf Ebrahimi	RtlCopyMemory(new_ptr, ptr, smaller_size);
833*9a0e4156SSadaf Ebrahimi	cs_winkernel_free(ptr);
834*9a0e4156SSadaf Ebrahimi
835*9a0e4156SSadaf Ebrahimi	return new_ptr;
836*9a0e4156SSadaf Ebrahimi}
837*9a0e4156SSadaf Ebrahimi```
838*9a0e4156SSadaf Ebrahimi
839*9a0e4156SSadaf Ebrahimi</details>
840*9a0e4156SSadaf Ebrahimi
841*9a0e4156SSadaf Ebrahimi> OSX kernel模式: `cs_realloc_t cs_mem_realloc = kern_os_realloc;`
842*9a0e4156SSadaf Ebrahimi
843*9a0e4156SSadaf Ebrahimi
844*9a0e4156SSadaf Ebrahimi### cs_free_t
845*9a0e4156SSadaf Ebrahimi
846*9a0e4156SSadaf Ebrahimi`typedef void (CAPSTONE_API *cs_free_t)(void *ptr);`
847*9a0e4156SSadaf Ebrahimi
848*9a0e4156SSadaf Ebrahimics释放内存
849*9a0e4156SSadaf Ebrahimi
850*9a0e4156SSadaf Ebrahimi用于`struct cs_opt_mem`,定义于cs.c
851*9a0e4156SSadaf Ebrahimi
852*9a0e4156SSadaf Ebrahimi用户模式: `cs_free_t cs_mem_free = free;`,调用系统free
853*9a0e4156SSadaf Ebrahimi
854*9a0e4156SSadaf EbrahimiWindows driver模式: `cs_free_t cs_mem_free = cs_winkernel_free;`
855*9a0e4156SSadaf Ebrahimi
856*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
857*9a0e4156SSadaf Ebrahimi
858*9a0e4156SSadaf Ebrahimi```cpp
859*9a0e4156SSadaf Ebrahimivoid CAPSTONE_API cs_winkernel_free(void *ptr)
860*9a0e4156SSadaf Ebrahimi{
861*9a0e4156SSadaf Ebrahimi	if (ptr) {
862*9a0e4156SSadaf Ebrahimi		ExFreePoolWithTag(CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data), CS_WINKERNEL_POOL_TAG);
863*9a0e4156SSadaf Ebrahimi	}
864*9a0e4156SSadaf Ebrahimi}
865*9a0e4156SSadaf Ebrahimi```
866*9a0e4156SSadaf Ebrahimi
867*9a0e4156SSadaf Ebrahimi</details>
868*9a0e4156SSadaf Ebrahimi
869*9a0e4156SSadaf Ebrahimi> OSX kernel模式:  `cs_free_t cs_mem_free = kern_os_free;`
870*9a0e4156SSadaf Ebrahimi
871*9a0e4156SSadaf Ebrahimi
872*9a0e4156SSadaf Ebrahimi
873*9a0e4156SSadaf Ebrahimi### cs_vsnprintf_t
874*9a0e4156SSadaf Ebrahimi
875*9a0e4156SSadaf Ebrahimi`int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap);`
876*9a0e4156SSadaf Ebrahimi
877*9a0e4156SSadaf Ebrahimi按size大小输出到字符串str中
878*9a0e4156SSadaf Ebrahimi
879*9a0e4156SSadaf Ebrahimi如果系统为wince,将使用_vsnprintf函数
880*9a0e4156SSadaf Ebrahimi
881*9a0e4156SSadaf Ebrahimivsnprintf ()和_vsnprintf()对于驱动程序都是可用的,但是它们有一些不同
882*9a0e4156SSadaf Ebrahimi
883*9a0e4156SSadaf Ebrahimi在需要返回值和设置空终止符时应使用vsnprintf()
884*9a0e4156SSadaf Ebrahimi
885*9a0e4156SSadaf EbrahimiWindows driver模式: `cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf;`
886*9a0e4156SSadaf Ebrahimi
887*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
888*9a0e4156SSadaf Ebrahimi
889*9a0e4156SSadaf Ebrahimi```cpp
890*9a0e4156SSadaf Ebrahimiint CAPSTONE_API cs_winkernel_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
891*9a0e4156SSadaf Ebrahimi{
892*9a0e4156SSadaf Ebrahimi	int result = _vsnprintf(buffer, count, format, argptr);
893*9a0e4156SSadaf Ebrahimi
894*9a0e4156SSadaf Ebrahimi	    // _vsnprintf()在字符串被截断时返回-1,在整个字符串被存储但“buffer”末尾没有“\0”时返回“count”。在这两种情况下,都需要手动添加空终止符。
895*9a0e4156SSadaf Ebrahimi	if (result == -1 || (size_t)result == count) {
896*9a0e4156SSadaf Ebrahimi		buffer[count - 1] = '\0';
897*9a0e4156SSadaf Ebrahimi	}
898*9a0e4156SSadaf Ebrahimi
899*9a0e4156SSadaf Ebrahimi	if (result == -1) {
900*9a0e4156SSadaf Ebrahimi		// 在返回-1时,函数必须获取并返回一些本来要写入的字符。因此,通过重试使用temp buffer进行相同的转换,这个缓冲区就可能足够大来完成格式化,并且获得很多本应写入的字符。
901*9a0e4156SSadaf Ebrahimi		char* tmp = cs_winkernel_malloc(0x1000);
902*9a0e4156SSadaf Ebrahimi		if (!tmp) {
903*9a0e4156SSadaf Ebrahimi			return result;
904*9a0e4156SSadaf Ebrahimi		}
905*9a0e4156SSadaf Ebrahimi
906*9a0e4156SSadaf Ebrahimi		result = _vsnprintf(tmp, 0x1000, format, argptr);
907*9a0e4156SSadaf Ebrahimi		NT_ASSERT(result != -1);
908*9a0e4156SSadaf Ebrahimi		cs_winkernel_free(tmp);
909*9a0e4156SSadaf Ebrahimi	}
910*9a0e4156SSadaf Ebrahimi
911*9a0e4156SSadaf Ebrahimi	return result;
912*9a0e4156SSadaf Ebrahimi}
913*9a0e4156SSadaf Ebrahimi```
914*9a0e4156SSadaf Ebrahimi
915*9a0e4156SSadaf Ebrahimi</details>
916*9a0e4156SSadaf Ebrahimi
917*9a0e4156SSadaf Ebrahimi> OSX kernel模式: `cs_vsnprintf_t cs_vsnprintf = vsnprintf;`,使用默认vsnprintf
918*9a0e4156SSadaf Ebrahimi
919*9a0e4156SSadaf Ebrahimi
920*9a0e4156SSadaf Ebrahimi
921*9a0e4156SSadaf Ebrahimi### cs_skipdata_cb_t
922*9a0e4156SSadaf Ebrahimi
923*9a0e4156SSadaf Ebrahimi`size_t (CAPSTONE_API *cs_skipdata_cb_t)(const uint8_t *code, size_t code_size, size_t offset, void *user_data);`
924*9a0e4156SSadaf Ebrahimi
925*9a0e4156SSadaf EbrahimiSKIPDATA选项的用户自定义回调函数。
926*9a0e4156SSadaf Ebrahimi
927*9a0e4156SSadaf Ebrahimi```
928*9a0e4156SSadaf Ebrahimicode:包含要分解的代码的输入缓冲区。和传递给cs_disasm()的缓冲区相同。
929*9a0e4156SSadaf Ebrahimicode_size:上面的code缓冲区的大小(以字节为单位)。
930*9a0e4156SSadaf Ebrahimioffset:上面提到的输入缓冲区code中当前检查字节的位置。
931*9a0e4156SSadaf Ebrahimiuser_data:用户数据通过cs_opt_skipdata结构中的@user_data字段传递给cs_option()。
932*9a0e4156SSadaf Ebrahimireturn:返回要跳过的字节数,或者0表示立即停止反汇编。
933*9a0e4156SSadaf Ebrahimi```
934*9a0e4156SSadaf Ebrahimi
935*9a0e4156SSadaf Ebrahimics_skipdata_cb_t在`struct cs_opt_skipdata`中调用
936*9a0e4156SSadaf Ebrahimi
937*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary>
938*9a0e4156SSadaf Ebrahimi
939*9a0e4156SSadaf Ebrahimi```cpp
940*9a0e4156SSadaf Ebrahimi#include <stdio.h>
941*9a0e4156SSadaf Ebrahimi#include <stdlib.h>
942*9a0e4156SSadaf Ebrahimi
943*9a0e4156SSadaf Ebrahimi#include "platform.h"
944*9a0e4156SSadaf Ebrahimi#include "capstone.h"
945*9a0e4156SSadaf Ebrahimi
946*9a0e4156SSadaf Ebrahimistruct platform {
947*9a0e4156SSadaf Ebrahimi	cs_arch arch;
948*9a0e4156SSadaf Ebrahimi	cs_mode mode;
949*9a0e4156SSadaf Ebrahimi	unsigned char* code;
950*9a0e4156SSadaf Ebrahimi	size_t size;
951*9a0e4156SSadaf Ebrahimi	const char* comment;
952*9a0e4156SSadaf Ebrahimi	cs_opt_type opt_type;
953*9a0e4156SSadaf Ebrahimi	cs_opt_value opt_value;
954*9a0e4156SSadaf Ebrahimi	cs_opt_type opt_skipdata;
955*9a0e4156SSadaf Ebrahimi	size_t skipdata;
956*9a0e4156SSadaf Ebrahimi};
957*9a0e4156SSadaf Ebrahimi
958*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len)  //输出机器码
959*9a0e4156SSadaf Ebrahimi{
960*9a0e4156SSadaf Ebrahimi	unsigned char* c;
961*9a0e4156SSadaf Ebrahimi
962*9a0e4156SSadaf Ebrahimi	printf("Code: ");
963*9a0e4156SSadaf Ebrahimi	for (c = str; c < str + len; c++) {
964*9a0e4156SSadaf Ebrahimi		printf("0x%02x ", *c & 0xff);
965*9a0e4156SSadaf Ebrahimi	}
966*9a0e4156SSadaf Ebrahimi	printf("\n");
967*9a0e4156SSadaf Ebrahimi}
968*9a0e4156SSadaf Ebrahimi
969*9a0e4156SSadaf Ebrahimistatic void test()
970*9a0e4156SSadaf Ebrahimi{
971*9a0e4156SSadaf Ebrahimi
972*9a0e4156SSadaf Ebrahimi#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x00\x91\x92"  //测试用机器码
973*9a0e4156SSadaf Ebrahimi
974*9a0e4156SSadaf Ebrahimi#define RANDOM_CODE "\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78"
975*9a0e4156SSadaf Ebrahimi
976*9a0e4156SSadaf Ebrahimi	cs_opt_skipdata skipdata = {
977*9a0e4156SSadaf Ebrahimi		// 把默认 "data" 描述符从 ".byte" 重命名为 "db"
978*9a0e4156SSadaf Ebrahimi		"db",
979*9a0e4156SSadaf Ebrahimi	};
980*9a0e4156SSadaf Ebrahimi
981*9a0e4156SSadaf Ebrahimi	struct platform platforms[2] = {         //以默认描述符和自定义描述符两种方式建立一个数组
982*9a0e4156SSadaf Ebrahimi		{
983*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
984*9a0e4156SSadaf Ebrahimi			CS_MODE_32,
985*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE32,
986*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE32) - 1,
987*9a0e4156SSadaf Ebrahimi			"X86 32 (Intel syntax) - Skip data",
988*9a0e4156SSadaf Ebrahimi		},
989*9a0e4156SSadaf Ebrahimi		{
990*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
991*9a0e4156SSadaf Ebrahimi			CS_MODE_32,
992*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE32,
993*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE32) - 1,
994*9a0e4156SSadaf Ebrahimi			"X86 32 (Intel syntax) - Skip data with custom mnemonic",
995*9a0e4156SSadaf Ebrahimi			CS_OPT_INVALID,
996*9a0e4156SSadaf Ebrahimi			CS_OPT_OFF,
997*9a0e4156SSadaf Ebrahimi			CS_OPT_SKIPDATA_SETUP,
998*9a0e4156SSadaf Ebrahimi			(size_t)& skipdata,
999*9a0e4156SSadaf Ebrahimi		},
1000*9a0e4156SSadaf Ebrahimi
1001*9a0e4156SSadaf Ebrahimi	};
1002*9a0e4156SSadaf Ebrahimi
1003*9a0e4156SSadaf Ebrahimi	csh handle;   //建立capstone句柄
1004*9a0e4156SSadaf Ebrahimi	uint64_t address = 0x1000;  //设置起始地址
1005*9a0e4156SSadaf Ebrahimi	cs_insn* insn;  //具体信息结构体
1006*9a0e4156SSadaf Ebrahimi	cs_err err;  //错误枚举
1007*9a0e4156SSadaf Ebrahimi	int i;
1008*9a0e4156SSadaf Ebrahimi	size_t count;  //成功反汇编行数
1009*9a0e4156SSadaf Ebrahimi
1010*9a0e4156SSadaf Ebrahimi	for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
1011*9a0e4156SSadaf Ebrahimi		printf("****************\n");
1012*9a0e4156SSadaf Ebrahimi		printf("Platform: %s\n", platforms[i].comment);
1013*9a0e4156SSadaf Ebrahimi		err = cs_open(platforms[i].arch, platforms[i].mode, &handle);  //错误检查
1014*9a0e4156SSadaf Ebrahimi		if (err) {
1015*9a0e4156SSadaf Ebrahimi			printf("Failed on cs_open() with error returned: %u\n", err);
1016*9a0e4156SSadaf Ebrahimi			abort();
1017*9a0e4156SSadaf Ebrahimi		}
1018*9a0e4156SSadaf Ebrahimi
1019*9a0e4156SSadaf Ebrahimi		if (platforms[i].opt_type)
1020*9a0e4156SSadaf Ebrahimi			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
1021*9a0e4156SSadaf Ebrahimi
1022*9a0e4156SSadaf Ebrahimi		// 打开SKIPDATA 模式
1023*9a0e4156SSadaf Ebrahimi		cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
1024*9a0e4156SSadaf Ebrahimi		cs_option(handle, platforms[i].opt_skipdata, platforms[i].skipdata);
1025*9a0e4156SSadaf Ebrahimi
1026*9a0e4156SSadaf Ebrahimi		count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
1027*9a0e4156SSadaf Ebrahimi		if (count) {
1028*9a0e4156SSadaf Ebrahimi			size_t j;
1029*9a0e4156SSadaf Ebrahimi
1030*9a0e4156SSadaf Ebrahimi			print_string_hex(platforms[i].code, platforms[i].size);
1031*9a0e4156SSadaf Ebrahimi			printf("Disasm:\n");
1032*9a0e4156SSadaf Ebrahimi
1033*9a0e4156SSadaf Ebrahimi			for (j = 0; j < count; j++) {  //输出汇编
1034*9a0e4156SSadaf Ebrahimi				printf("0x%" PRIx64 ":\t%s\t\t%s\n",
1035*9a0e4156SSadaf Ebrahimi					insn[j].address, insn[j].mnemonic, insn[j].op_str);
1036*9a0e4156SSadaf Ebrahimi			}
1037*9a0e4156SSadaf Ebrahimi
1038*9a0e4156SSadaf Ebrahimi			// 最后一行代码后打印偏移
1039*9a0e4156SSadaf Ebrahimi			printf("0x%" PRIx64 ":\n", insn[j - 1].address + insn[j - 1].size);
1040*9a0e4156SSadaf Ebrahimi
1041*9a0e4156SSadaf Ebrahimi			// 释放cs_disasm()申请的内存
1042*9a0e4156SSadaf Ebrahimi			cs_free(insn, count);
1043*9a0e4156SSadaf Ebrahimi		}
1044*9a0e4156SSadaf Ebrahimi		else {
1045*9a0e4156SSadaf Ebrahimi			printf("****************\n");
1046*9a0e4156SSadaf Ebrahimi			printf("Platform: %s\n", platforms[i].comment);
1047*9a0e4156SSadaf Ebrahimi			print_string_hex(platforms[i].code, platforms[i].size);
1048*9a0e4156SSadaf Ebrahimi			printf("ERROR: Failed to disasm given code!\n");
1049*9a0e4156SSadaf Ebrahimi			abort();
1050*9a0e4156SSadaf Ebrahimi		}
1051*9a0e4156SSadaf Ebrahimi
1052*9a0e4156SSadaf Ebrahimi		printf("\n");
1053*9a0e4156SSadaf Ebrahimi
1054*9a0e4156SSadaf Ebrahimi		cs_close(&handle);
1055*9a0e4156SSadaf Ebrahimi	}
1056*9a0e4156SSadaf Ebrahimi}
1057*9a0e4156SSadaf Ebrahimi
1058*9a0e4156SSadaf Ebrahimiint main()
1059*9a0e4156SSadaf Ebrahimi{
1060*9a0e4156SSadaf Ebrahimi	test();
1061*9a0e4156SSadaf Ebrahimi
1062*9a0e4156SSadaf Ebrahimi	return 0;
1063*9a0e4156SSadaf Ebrahimi}
1064*9a0e4156SSadaf Ebrahimi```
1065*9a0e4156SSadaf Ebrahimi
1066*9a0e4156SSadaf Ebrahimi</details>
1067*9a0e4156SSadaf Ebrahimi
1068*9a0e4156SSadaf Ebrahimi运行结果如下,默认的.byte数据类型被改为db描述符
1069*9a0e4156SSadaf Ebrahimi
1070*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/11.jpg)
1071*9a0e4156SSadaf Ebrahimi
1072*9a0e4156SSadaf Ebrahimi
1073*9a0e4156SSadaf Ebrahimi
1074*9a0e4156SSadaf Ebrahimi
1075*9a0e4156SSadaf Ebrahimi### cs_open
1076*9a0e4156SSadaf Ebrahimi
1077*9a0e4156SSadaf Ebrahimi`cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle);`
1078*9a0e4156SSadaf Ebrahimi
1079*9a0e4156SSadaf Ebrahimi初始化cs句柄
1080*9a0e4156SSadaf Ebrahimi
1081*9a0e4156SSadaf Ebrahimi```
1082*9a0e4156SSadaf Ebrahimiarch: 架构类型 (CS_ARCH_*)
1083*9a0e4156SSadaf Ebrahimimode: 硬件模式. CS_MODE_*在cs_mode数据类型中可查
1084*9a0e4156SSadaf Ebrahimihandle: 指向句柄, 返回时更新
1085*9a0e4156SSadaf Ebrahimireturn: 创建成功返回CS_ERR_OK,否则返回cs_err枚举中对应的错误信息
1086*9a0e4156SSadaf Ebrahimi```
1087*9a0e4156SSadaf Ebrahimi
1088*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
1089*9a0e4156SSadaf Ebrahimi
1090*9a0e4156SSadaf Ebrahimi```cpp
1091*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
1092*9a0e4156SSadaf Ebrahimi{
1093*9a0e4156SSadaf Ebrahimi	cs_err err;
1094*9a0e4156SSadaf Ebrahimi	struct cs_struct *ud;
1095*9a0e4156SSadaf Ebrahimi	if (!cs_mem_malloc || !cs_mem_calloc || !cs_mem_realloc || !cs_mem_free || !cs_vsnprintf)
1096*9a0e4156SSadaf Ebrahimi		// Error: 使用cs_open()前, 必须使用cs_option(CS_OPT_MEM)进行动态内存管理的初始化
1097*9a0e4156SSadaf Ebrahimi		return CS_ERR_MEMSETUP;
1098*9a0e4156SSadaf Ebrahimi
1099*9a0e4156SSadaf Ebrahimi	if (arch < CS_ARCH_MAX && cs_arch_init[arch]) {
1100*9a0e4156SSadaf Ebrahimi		// 验证架构是否使用,方式:架构在枚举中且可初始化
1101*9a0e4156SSadaf Ebrahimi		if (mode & cs_arch_disallowed_mode_mask[arch]) {
1102*9a0e4156SSadaf Ebrahimi			*handle = 0;
1103*9a0e4156SSadaf Ebrahimi			return CS_ERR_MODE;
1104*9a0e4156SSadaf Ebrahimi		}
1105*9a0e4156SSadaf Ebrahimi
1106*9a0e4156SSadaf Ebrahimi		ud = cs_mem_calloc(1, sizeof(*ud));
1107*9a0e4156SSadaf Ebrahimi		if (!ud) {
1108*9a0e4156SSadaf Ebrahimi			// 内存不足
1109*9a0e4156SSadaf Ebrahimi			return CS_ERR_MEM;
1110*9a0e4156SSadaf Ebrahimi		}
1111*9a0e4156SSadaf Ebrahimi
1112*9a0e4156SSadaf Ebrahimi		ud->errnum = CS_ERR_OK;
1113*9a0e4156SSadaf Ebrahimi		ud->arch = arch;
1114*9a0e4156SSadaf Ebrahimi		ud->mode = mode;
1115*9a0e4156SSadaf Ebrahimi		// 默认情况指令不打开detail模式
1116*9a0e4156SSadaf Ebrahimi		ud->detail = CS_OPT_OFF;
1117*9a0e4156SSadaf Ebrahimi
1118*9a0e4156SSadaf Ebrahimi		// 默认skipdata设置
1119*9a0e4156SSadaf Ebrahimi		ud->skipdata_setup.mnemonic = SKIPDATA_MNEM;
1120*9a0e4156SSadaf Ebrahimi
1121*9a0e4156SSadaf Ebrahimi		err = cs_arch_init[ud->arch](ud);
1122*9a0e4156SSadaf Ebrahimi		if (err) {
1123*9a0e4156SSadaf Ebrahimi			cs_mem_free(ud);
1124*9a0e4156SSadaf Ebrahimi			*handle = 0;
1125*9a0e4156SSadaf Ebrahimi			return err;
1126*9a0e4156SSadaf Ebrahimi		}
1127*9a0e4156SSadaf Ebrahimi
1128*9a0e4156SSadaf Ebrahimi		*handle = (uintptr_t)ud;
1129*9a0e4156SSadaf Ebrahimi
1130*9a0e4156SSadaf Ebrahimi		return CS_ERR_OK;
1131*9a0e4156SSadaf Ebrahimi	} else {
1132*9a0e4156SSadaf Ebrahimi		*handle = 0;
1133*9a0e4156SSadaf Ebrahimi		return CS_ERR_ARCH;
1134*9a0e4156SSadaf Ebrahimi	}
1135*9a0e4156SSadaf Ebrahimi}
1136*9a0e4156SSadaf Ebrahimi```
1137*9a0e4156SSadaf Ebrahimi
1138*9a0e4156SSadaf Ebrahimi其中,cs_struct结构体包含更多细节设定,如下
1139*9a0e4156SSadaf Ebrahimi
1140*9a0e4156SSadaf Ebrahimi```cpp
1141*9a0e4156SSadaf Ebrahimistruct cs_struct {
1142*9a0e4156SSadaf Ebrahimi	cs_arch arch;
1143*9a0e4156SSadaf Ebrahimi	cs_mode mode;
1144*9a0e4156SSadaf Ebrahimi	Printer_t printer;	// 打印asm
1145*9a0e4156SSadaf Ebrahimi	void *printer_info; // 打印信息
1146*9a0e4156SSadaf Ebrahimi	Disasm_t disasm;	// 反编译
1147*9a0e4156SSadaf Ebrahimi	void *getinsn_info; // 打印辅助信息
1148*9a0e4156SSadaf Ebrahimi	GetName_t reg_name;
1149*9a0e4156SSadaf Ebrahimi	GetName_t insn_name;
1150*9a0e4156SSadaf Ebrahimi	GetName_t group_name;
1151*9a0e4156SSadaf Ebrahimi	GetID_t insn_id;
1152*9a0e4156SSadaf Ebrahimi	PostPrinter_t post_printer;
1153*9a0e4156SSadaf Ebrahimi	cs_err errnum;
1154*9a0e4156SSadaf Ebrahimi	ARM_ITStatus ITBlock;	// ARM特殊选项
1155*9a0e4156SSadaf Ebrahimi	cs_opt_value detail, imm_unsigned;
1156*9a0e4156SSadaf Ebrahimi	int syntax;	//ARM, Mips & PPC等架构的基本asm语法打印
1157*9a0e4156SSadaf Ebrahimi	bool doing_mem;	// 在InstPrinter代码中处理内存操作数
1158*9a0e4156SSadaf Ebrahimi	unsigned short *insn_cache;	//为mapping.c建立缓存索引
1159*9a0e4156SSadaf Ebrahimi	GetRegisterName_t get_regname;
1160*9a0e4156SSadaf Ebrahimi	bool skipdata;	// 如果反编译时要跳过数据,该项设置为True
1161*9a0e4156SSadaf Ebrahimi	uint8_t skipdata_size;	//要跳过bytes的数量
1162*9a0e4156SSadaf Ebrahimi	cs_opt_skipdata skipdata_setup;	// 自定义skipdata设置
1163*9a0e4156SSadaf Ebrahimi	const uint8_t *regsize_map;	//映射register大小 (目前仅支持x86)
1164*9a0e4156SSadaf Ebrahimi	GetRegisterAccess_t reg_access;
1165*9a0e4156SSadaf Ebrahimi	struct insn_mnem *mnem_list;	// 自定义指令助记符的链接list
1166*9a0e4156SSadaf Ebrahimi};
1167*9a0e4156SSadaf Ebrahimi```
1168*9a0e4156SSadaf Ebrahimi
1169*9a0e4156SSadaf Ebrahimi</details>
1170*9a0e4156SSadaf Ebrahimi
1171*9a0e4156SSadaf Ebrahimi示例(创建一个x86_64类型的cs句柄)
1172*9a0e4156SSadaf Ebrahimi
1173*9a0e4156SSadaf Ebrahimi`cs_open(CS_ARCH_X86, CS_MODE_64, &handle)`
1174*9a0e4156SSadaf Ebrahimi
1175*9a0e4156SSadaf Ebrahimi
1176*9a0e4156SSadaf Ebrahimi### cs_close
1177*9a0e4156SSadaf Ebrahimi
1178*9a0e4156SSadaf Ebrahimi`cs_err CAPSTONE_API cs_close(csh *handle);`
1179*9a0e4156SSadaf Ebrahimi
1180*9a0e4156SSadaf Ebrahimi释放句柄
1181*9a0e4156SSadaf Ebrahimi
1182*9a0e4156SSadaf Ebrahimi```
1183*9a0e4156SSadaf Ebrahimihandle: 指向一个cs_open()打开的句柄
1184*9a0e4156SSadaf Ebrahimireturn: 释放成功返回CS_ERR_OK,否则返回cs_err枚举的错误信息
1185*9a0e4156SSadaf Ebrahimi```
1186*9a0e4156SSadaf Ebrahimi
1187*9a0e4156SSadaf Ebrahimi释放句柄实质为将句柄值设置为0
1188*9a0e4156SSadaf Ebrahimi
1189*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
1190*9a0e4156SSadaf Ebrahimi
1191*9a0e4156SSadaf Ebrahimi```cpp
1192*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_close(csh *handle)
1193*9a0e4156SSadaf Ebrahimi{
1194*9a0e4156SSadaf Ebrahimi	struct cs_struct *ud;
1195*9a0e4156SSadaf Ebrahimi	struct insn_mnem *next, *tmp;
1196*9a0e4156SSadaf Ebrahimi
1197*9a0e4156SSadaf Ebrahimi	if (*handle == 0)
1198*9a0e4156SSadaf Ebrahimi		// 句柄不可用
1199*9a0e4156SSadaf Ebrahimi		return CS_ERR_CSH;
1200*9a0e4156SSadaf Ebrahimi
1201*9a0e4156SSadaf Ebrahimi	ud = (struct cs_struct *)(*handle);
1202*9a0e4156SSadaf Ebrahimi
1203*9a0e4156SSadaf Ebrahimi	if (ud->printer_info)
1204*9a0e4156SSadaf Ebrahimi		cs_mem_free(ud->printer_info);
1205*9a0e4156SSadaf Ebrahimi
1206*9a0e4156SSadaf Ebrahimi	// 释放自定义助记符的链接list
1207*9a0e4156SSadaf Ebrahimi	tmp = ud->mnem_list;
1208*9a0e4156SSadaf Ebrahimi	while(tmp) {
1209*9a0e4156SSadaf Ebrahimi		next = tmp->next;
1210*9a0e4156SSadaf Ebrahimi		cs_mem_free(tmp);
1211*9a0e4156SSadaf Ebrahimi		tmp = next;
1212*9a0e4156SSadaf Ebrahimi	}
1213*9a0e4156SSadaf Ebrahimi
1214*9a0e4156SSadaf Ebrahimi	cs_mem_free(ud->insn_cache);
1215*9a0e4156SSadaf Ebrahimi
1216*9a0e4156SSadaf Ebrahimi	memset(ud, 0, sizeof(*ud));
1217*9a0e4156SSadaf Ebrahimi	cs_mem_free(ud);
1218*9a0e4156SSadaf Ebrahimi
1219*9a0e4156SSadaf Ebrahimi	// handle值设置为0,保证这个句柄在cs_close()释放后不可使用
1220*9a0e4156SSadaf Ebrahimi	*handle = 0;
1221*9a0e4156SSadaf Ebrahimi
1222*9a0e4156SSadaf Ebrahimi	return CS_ERR_OK;
1223*9a0e4156SSadaf Ebrahimi}
1224*9a0e4156SSadaf Ebrahimi```
1225*9a0e4156SSadaf Ebrahimi
1226*9a0e4156SSadaf Ebrahimi</details>
1227*9a0e4156SSadaf Ebrahimi
1228*9a0e4156SSadaf Ebrahimi示例
1229*9a0e4156SSadaf Ebrahimi
1230*9a0e4156SSadaf Ebrahimi`cs_close(&handle);`
1231*9a0e4156SSadaf Ebrahimi
1232*9a0e4156SSadaf Ebrahimi
1233*9a0e4156SSadaf Ebrahimi### cs_option
1234*9a0e4156SSadaf Ebrahimi
1235*9a0e4156SSadaf Ebrahimi`cs_err CAPSTONE_API cs_option(csh handle, cs_opt_type type, size_t value);`
1236*9a0e4156SSadaf Ebrahimi
1237*9a0e4156SSadaf Ebrahimi反编译引擎的运行时选项
1238*9a0e4156SSadaf Ebrahimi
1239*9a0e4156SSadaf Ebrahimi```
1240*9a0e4156SSadaf Ebrahimihandle: cs_open()打开的句柄
1241*9a0e4156SSadaf Ebrahimitype: 设置选项的类型
1242*9a0e4156SSadaf Ebrahimivalue: 与type对应的选项值
1243*9a0e4156SSadaf Ebrahimireturn: 设置成功返回CS_ERR_OK,否则返回cs_err枚举的错误信息
1244*9a0e4156SSadaf Ebrahimi```
1245*9a0e4156SSadaf Ebrahimi
1246*9a0e4156SSadaf Ebrahimi注意: 在CS_OPT_MEM的情况下,handle可以是任何值,因此cs_option(handle, CS_OPT_MEM, value)必须在cs_open()之前被调用
1247*9a0e4156SSadaf Ebrahimi
1248*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
1249*9a0e4156SSadaf Ebrahimi
1250*9a0e4156SSadaf Ebrahimi```cpp
1251*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
1252*9a0e4156SSadaf Ebrahimi{
1253*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
1254*9a0e4156SSadaf Ebrahimi	cs_opt_mnem *opt;
1255*9a0e4156SSadaf Ebrahimi
1256*9a0e4156SSadaf Ebrahimi	// 支持在所有API前支持 (even cs_open())
1257*9a0e4156SSadaf Ebrahimi	if (type == CS_OPT_MEM) {
1258*9a0e4156SSadaf Ebrahimi		cs_opt_mem *mem = (cs_opt_mem *)value;
1259*9a0e4156SSadaf Ebrahimi
1260*9a0e4156SSadaf Ebrahimi		cs_mem_malloc = mem->malloc;
1261*9a0e4156SSadaf Ebrahimi		cs_mem_calloc = mem->calloc;
1262*9a0e4156SSadaf Ebrahimi		cs_mem_realloc = mem->realloc;
1263*9a0e4156SSadaf Ebrahimi		cs_mem_free = mem->free;
1264*9a0e4156SSadaf Ebrahimi		cs_vsnprintf = mem->vsnprintf;
1265*9a0e4156SSadaf Ebrahimi
1266*9a0e4156SSadaf Ebrahimi		return CS_ERR_OK;
1267*9a0e4156SSadaf Ebrahimi	}
1268*9a0e4156SSadaf Ebrahimi
1269*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
1270*9a0e4156SSadaf Ebrahimi	if (!handle)
1271*9a0e4156SSadaf Ebrahimi		return CS_ERR_CSH;
1272*9a0e4156SSadaf Ebrahimi
1273*9a0e4156SSadaf Ebrahimi	switch(type) {
1274*9a0e4156SSadaf Ebrahimi		default:
1275*9a0e4156SSadaf Ebrahimi			break;
1276*9a0e4156SSadaf Ebrahimi
1277*9a0e4156SSadaf Ebrahimi		case CS_OPT_UNSIGNED:
1278*9a0e4156SSadaf Ebrahimi			handle->imm_unsigned = (cs_opt_value)value;
1279*9a0e4156SSadaf Ebrahimi			return CS_ERR_OK;
1280*9a0e4156SSadaf Ebrahimi
1281*9a0e4156SSadaf Ebrahimi		case CS_OPT_DETAIL:
1282*9a0e4156SSadaf Ebrahimi			handle->detail = (cs_opt_value)value;
1283*9a0e4156SSadaf Ebrahimi			return CS_ERR_OK;
1284*9a0e4156SSadaf Ebrahimi
1285*9a0e4156SSadaf Ebrahimi		case CS_OPT_SKIPDATA:
1286*9a0e4156SSadaf Ebrahimi			handle->skipdata = (value == CS_OPT_ON);
1287*9a0e4156SSadaf Ebrahimi			if (handle->skipdata) {
1288*9a0e4156SSadaf Ebrahimi				if (handle->skipdata_size == 0) {
1289*9a0e4156SSadaf Ebrahimi					handle->skipdata_size = skipdata_size(handle);
1290*9a0e4156SSadaf Ebrahimi				}
1291*9a0e4156SSadaf Ebrahimi			}
1292*9a0e4156SSadaf Ebrahimi			return CS_ERR_OK;
1293*9a0e4156SSadaf Ebrahimi
1294*9a0e4156SSadaf Ebrahimi		case CS_OPT_SKIPDATA_SETUP:
1295*9a0e4156SSadaf Ebrahimi			if (value)
1296*9a0e4156SSadaf Ebrahimi				handle->skipdata_setup = *((cs_opt_skipdata *)value);
1297*9a0e4156SSadaf Ebrahimi			return CS_ERR_OK;
1298*9a0e4156SSadaf Ebrahimi
1299*9a0e4156SSadaf Ebrahimi		case CS_OPT_MNEMONIC:
1300*9a0e4156SSadaf Ebrahimi			opt = (cs_opt_mnem *)value;
1301*9a0e4156SSadaf Ebrahimi			if (opt->id) {
1302*9a0e4156SSadaf Ebrahimi				if (opt->mnemonic) {
1303*9a0e4156SSadaf Ebrahimi					struct insn_mnem *tmp;
1304*9a0e4156SSadaf Ebrahimi
1305*9a0e4156SSadaf Ebrahimi					// 添加新指令或替换现有指令
1306*9a0e4156SSadaf Ebrahimi					// 查看当前insn释放在list中
1307*9a0e4156SSadaf Ebrahimi					tmp = handle->mnem_list;
1308*9a0e4156SSadaf Ebrahimi					while(tmp) {
1309*9a0e4156SSadaf Ebrahimi						if (tmp->insn.id == opt->id) {
1310*9a0e4156SSadaf Ebrahimi							// f找到指令,替换助记符
1311*9a0e4156SSadaf Ebrahimi							(void)strncpy(tmp->insn.mnemonic, opt->mnemonic, sizeof(tmp->insn.mnemonic) - 1);
1312*9a0e4156SSadaf Ebrahimi							tmp->insn.mnemonic[sizeof(tmp->insn.mnemonic) - 1] = '\0';
1313*9a0e4156SSadaf Ebrahimi							break;
1314*9a0e4156SSadaf Ebrahimi						}
1315*9a0e4156SSadaf Ebrahimi						tmp = tmp->next;
1316*9a0e4156SSadaf Ebrahimi					}
1317*9a0e4156SSadaf Ebrahimi
1318*9a0e4156SSadaf Ebrahimi					// 2. 如果没有就添加这条指令
1319*9a0e4156SSadaf Ebrahimi					if (!tmp) {
1320*9a0e4156SSadaf Ebrahimi						tmp = cs_mem_malloc(sizeof(*tmp));
1321*9a0e4156SSadaf Ebrahimi						tmp->insn.id = opt->id;
1322*9a0e4156SSadaf Ebrahimi						(void)strncpy(tmp->insn.mnemonic, opt->mnemonic, sizeof(tmp->insn.mnemonic) - 1);
1323*9a0e4156SSadaf Ebrahimi						tmp->insn.mnemonic[sizeof(tmp->insn.mnemonic) - 1] = '\0';
1324*9a0e4156SSadaf Ebrahimi						// 新指令放在list最前面
1325*9a0e4156SSadaf Ebrahimi						tmp->next = handle->mnem_list;
1326*9a0e4156SSadaf Ebrahimi						handle->mnem_list = tmp;
1327*9a0e4156SSadaf Ebrahimi					}
1328*9a0e4156SSadaf Ebrahimi					return CS_ERR_OK;
1329*9a0e4156SSadaf Ebrahimi				} else {
1330*9a0e4156SSadaf Ebrahimi					struct insn_mnem *prev, *tmp;
1331*9a0e4156SSadaf Ebrahimi
1332*9a0e4156SSadaf Ebrahimi					tmp = handle->mnem_list;
1333*9a0e4156SSadaf Ebrahimi					prev = tmp;
1334*9a0e4156SSadaf Ebrahimi					while(tmp) {
1335*9a0e4156SSadaf Ebrahimi						if (tmp->insn.id == opt->id) {
1336*9a0e4156SSadaf Ebrahimi							// 删除指令
1337*9a0e4156SSadaf Ebrahimi							if (tmp == prev) {
1338*9a0e4156SSadaf Ebrahimi								handle->mnem_list = tmp->next;
1339*9a0e4156SSadaf Ebrahimi							} else {
1340*9a0e4156SSadaf Ebrahimi								prev->next = tmp->next;
1341*9a0e4156SSadaf Ebrahimi							}
1342*9a0e4156SSadaf Ebrahimi							cs_mem_free(tmp);
1343*9a0e4156SSadaf Ebrahimi							break;
1344*9a0e4156SSadaf Ebrahimi						}
1345*9a0e4156SSadaf Ebrahimi						prev = tmp;
1346*9a0e4156SSadaf Ebrahimi						tmp = tmp->next;
1347*9a0e4156SSadaf Ebrahimi					}
1348*9a0e4156SSadaf Ebrahimi				}
1349*9a0e4156SSadaf Ebrahimi			}
1350*9a0e4156SSadaf Ebrahimi			return CS_ERR_OK;
1351*9a0e4156SSadaf Ebrahimi
1352*9a0e4156SSadaf Ebrahimi		case CS_OPT_MODE:
1353*9a0e4156SSadaf Ebrahimi			// 验证所请求的模式是否有效
1354*9a0e4156SSadaf Ebrahimi			if (value & cs_arch_disallowed_mode_mask[handle->arch]) {
1355*9a0e4156SSadaf Ebrahimi				return CS_ERR_OPTION;
1356*9a0e4156SSadaf Ebrahimi			}
1357*9a0e4156SSadaf Ebrahimi			break;
1358*9a0e4156SSadaf Ebrahimi	}
1359*9a0e4156SSadaf Ebrahimi
1360*9a0e4156SSadaf Ebrahimi	return cs_arch_option[handle->arch](handle, type, value);
1361*9a0e4156SSadaf Ebrahimi}
1362*9a0e4156SSadaf Ebrahimi```
1363*9a0e4156SSadaf Ebrahimi</details>
1364*9a0e4156SSadaf Ebrahimi
1365*9a0e4156SSadaf Ebrahimi
1366*9a0e4156SSadaf Ebrahimi<details><summary> 示例,更改反汇编后显示的语法 </summary>
1367*9a0e4156SSadaf Ebrahimi
1368*9a0e4156SSadaf Ebrahimi```cpp
1369*9a0e4156SSadaf Ebrahimi#include <iostream>
1370*9a0e4156SSadaf Ebrahimi#include <stdio.h>
1371*9a0e4156SSadaf Ebrahimi
1372*9a0e4156SSadaf Ebrahimi#include "capstone.h"
1373*9a0e4156SSadaf Ebrahimi#include "platform.h"
1374*9a0e4156SSadaf Ebrahimi
1375*9a0e4156SSadaf Ebrahimiusing namespace std;
1376*9a0e4156SSadaf Ebrahimi
1377*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00"
1378*9a0e4156SSadaf Ebrahimi
1379*9a0e4156SSadaf Ebrahimiint main(void)
1380*9a0e4156SSadaf Ebrahimi{
1381*9a0e4156SSadaf Ebrahimi	csh handle;
1382*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
1383*9a0e4156SSadaf Ebrahimi	size_t count;
1384*9a0e4156SSadaf Ebrahimi
1385*9a0e4156SSadaf Ebrahimi	if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) {
1386*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to initialize engine!\n");
1387*9a0e4156SSadaf Ebrahimi		return -1;
1388*9a0e4156SSadaf Ebrahimi	}
1389*9a0e4156SSadaf Ebrahimi	cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);  // 以AT&T语法显示
1390*9a0e4156SSadaf Ebrahimi	count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn);
1391*9a0e4156SSadaf Ebrahimi	if (count) {
1392*9a0e4156SSadaf Ebrahimi		size_t j;
1393*9a0e4156SSadaf Ebrahimi
1394*9a0e4156SSadaf Ebrahimi		for (j = 0; j < count; j++) {
1395*9a0e4156SSadaf Ebrahimi			printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
1396*9a0e4156SSadaf Ebrahimi		}
1397*9a0e4156SSadaf Ebrahimi
1398*9a0e4156SSadaf Ebrahimi		cs_free(insn, count);
1399*9a0e4156SSadaf Ebrahimi	}
1400*9a0e4156SSadaf Ebrahimi	else
1401*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to disassemble given code!\n");
1402*9a0e4156SSadaf Ebrahimi
1403*9a0e4156SSadaf Ebrahimi	cs_close(&handle);
1404*9a0e4156SSadaf Ebrahimi
1405*9a0e4156SSadaf Ebrahimi	return 0;
1406*9a0e4156SSadaf Ebrahimi}
1407*9a0e4156SSadaf Ebrahimi```
1408*9a0e4156SSadaf Ebrahimi
1409*9a0e4156SSadaf Ebrahimi</details>
1410*9a0e4156SSadaf Ebrahimi
1411*9a0e4156SSadaf Ebrahimi输出
1412*9a0e4156SSadaf Ebrahimi
1413*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/16.jpg)
1414*9a0e4156SSadaf Ebrahimi
1415*9a0e4156SSadaf Ebrahimi
1416*9a0e4156SSadaf Ebrahimi### cs_errno
1417*9a0e4156SSadaf Ebrahimi
1418*9a0e4156SSadaf Ebrahimi`cs_err CAPSTONE_API cs_errno(csh handle);`
1419*9a0e4156SSadaf Ebrahimi
1420*9a0e4156SSadaf EbrahimiAPI出错时返回错误消息
1421*9a0e4156SSadaf Ebrahimi
1422*9a0e4156SSadaf Ebrahimi```
1423*9a0e4156SSadaf Ebrahimihandle: cs_open()打开的句柄
1424*9a0e4156SSadaf Ebrahimireturn: 无错误返回CS_ERR_OK,否则返回cs_err枚举的错误信息
1425*9a0e4156SSadaf Ebrahimi```
1426*9a0e4156SSadaf Ebrahimi
1427*9a0e4156SSadaf Ebrahimi判断到句柄不存在直接返回CS_ERR_CSH
1428*9a0e4156SSadaf Ebrahimi
1429*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary>
1430*9a0e4156SSadaf Ebrahimi
1431*9a0e4156SSadaf Ebrahimi```cpp
1432*9a0e4156SSadaf Ebrahimi#include <iostream>
1433*9a0e4156SSadaf Ebrahimi#include <stdio.h>
1434*9a0e4156SSadaf Ebrahimi
1435*9a0e4156SSadaf Ebrahimi#include "capstone.h"
1436*9a0e4156SSadaf Ebrahimi#include "platform.h"
1437*9a0e4156SSadaf Ebrahimi
1438*9a0e4156SSadaf Ebrahimiusing namespace std;
1439*9a0e4156SSadaf Ebrahimi
1440*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00"
1441*9a0e4156SSadaf Ebrahimi
1442*9a0e4156SSadaf Ebrahimiint main(void)
1443*9a0e4156SSadaf Ebrahimi{
1444*9a0e4156SSadaf Ebrahimi	csh handle = 0;
1445*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
1446*9a0e4156SSadaf Ebrahimi	size_t count;
1447*9a0e4156SSadaf Ebrahimi
1448*9a0e4156SSadaf Ebrahimi	if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) {
1449*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to initialize engine!\n");
1450*9a0e4156SSadaf Ebrahimi		return -1;
1451*9a0e4156SSadaf Ebrahimi	}
1452*9a0e4156SSadaf Ebrahimi
1453*9a0e4156SSadaf Ebrahimi	cs_close(&handle);
1454*9a0e4156SSadaf Ebrahimi	std::cout << cs_errno(handle);    //关闭句柄后检查将报错
1455*9a0e4156SSadaf Ebrahimi	return 0;
1456*9a0e4156SSadaf Ebrahimi}
1457*9a0e4156SSadaf Ebrahimi```
1458*9a0e4156SSadaf Ebrahimi
1459*9a0e4156SSadaf Ebrahimi</details>
1460*9a0e4156SSadaf Ebrahimi
1461*9a0e4156SSadaf Ebrahimi输出,错误码4即CS_ERR_CSH
1462*9a0e4156SSadaf Ebrahimi
1463*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/17.jpg)
1464*9a0e4156SSadaf Ebrahimi
1465*9a0e4156SSadaf Ebrahimi
1466*9a0e4156SSadaf Ebrahimi### cs_strerror
1467*9a0e4156SSadaf Ebrahimi
1468*9a0e4156SSadaf Ebrahimi`const char * CAPSTONE_API cs_strerror(cs_err code);`
1469*9a0e4156SSadaf Ebrahimi
1470*9a0e4156SSadaf Ebrahimi将上个API输出的错误码转换为详细错误信息
1471*9a0e4156SSadaf Ebrahimi
1472*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
1473*9a0e4156SSadaf Ebrahimi
1474*9a0e4156SSadaf Ebrahimi```cpp
1475*9a0e4156SSadaf Ebrahimiconst char * CAPSTONE_API cs_strerror(cs_err code)
1476*9a0e4156SSadaf Ebrahimi{
1477*9a0e4156SSadaf Ebrahimi	switch(code) {
1478*9a0e4156SSadaf Ebrahimi		default:
1479*9a0e4156SSadaf Ebrahimi			return "Unknown error code";
1480*9a0e4156SSadaf Ebrahimi		case CS_ERR_OK:
1481*9a0e4156SSadaf Ebrahimi			return "OK (CS_ERR_OK)";
1482*9a0e4156SSadaf Ebrahimi		case CS_ERR_MEM:
1483*9a0e4156SSadaf Ebrahimi			return "Out of memory (CS_ERR_MEM)";
1484*9a0e4156SSadaf Ebrahimi		case CS_ERR_ARCH:
1485*9a0e4156SSadaf Ebrahimi			return "Invalid/unsupported architecture(CS_ERR_ARCH)";
1486*9a0e4156SSadaf Ebrahimi		case CS_ERR_HANDLE:
1487*9a0e4156SSadaf Ebrahimi			return "Invalid handle (CS_ERR_HANDLE)";
1488*9a0e4156SSadaf Ebrahimi		case CS_ERR_CSH:
1489*9a0e4156SSadaf Ebrahimi			return "Invalid csh (CS_ERR_CSH)";
1490*9a0e4156SSadaf Ebrahimi		case CS_ERR_MODE:
1491*9a0e4156SSadaf Ebrahimi			return "Invalid mode (CS_ERR_MODE)";
1492*9a0e4156SSadaf Ebrahimi		case CS_ERR_OPTION:
1493*9a0e4156SSadaf Ebrahimi			return "Invalid option (CS_ERR_OPTION)";
1494*9a0e4156SSadaf Ebrahimi		case CS_ERR_DETAIL:
1495*9a0e4156SSadaf Ebrahimi			return "Details are unavailable (CS_ERR_DETAIL)";
1496*9a0e4156SSadaf Ebrahimi		case CS_ERR_MEMSETUP:
1497*9a0e4156SSadaf Ebrahimi			return "Dynamic memory management uninitialized (CS_ERR_MEMSETUP)";
1498*9a0e4156SSadaf Ebrahimi		case CS_ERR_VERSION:
1499*9a0e4156SSadaf Ebrahimi			return "Different API version between core & binding (CS_ERR_VERSION)";
1500*9a0e4156SSadaf Ebrahimi		case CS_ERR_DIET:
1501*9a0e4156SSadaf Ebrahimi			return "Information irrelevant in diet engine (CS_ERR_DIET)";
1502*9a0e4156SSadaf Ebrahimi		case CS_ERR_SKIPDATA:
1503*9a0e4156SSadaf Ebrahimi			return "Information irrelevant for 'data' instruction in SKIPDATA mode (CS_ERR_SKIPDATA)";
1504*9a0e4156SSadaf Ebrahimi		case CS_ERR_X86_ATT:
1505*9a0e4156SSadaf Ebrahimi			return "AT&T syntax is unavailable (CS_ERR_X86_ATT)";
1506*9a0e4156SSadaf Ebrahimi		case CS_ERR_X86_INTEL:
1507*9a0e4156SSadaf Ebrahimi			return "INTEL syntax is unavailable (CS_ERR_X86_INTEL)";
1508*9a0e4156SSadaf Ebrahimi		case CS_ERR_X86_MASM:
1509*9a0e4156SSadaf Ebrahimi			return "MASM syntax is unavailable (CS_ERR_X86_MASM)";
1510*9a0e4156SSadaf Ebrahimi	}
1511*9a0e4156SSadaf Ebrahimi}
1512*9a0e4156SSadaf Ebrahimi```
1513*9a0e4156SSadaf Ebrahimi</details>
1514*9a0e4156SSadaf Ebrahimi
1515*9a0e4156SSadaf Ebrahimi
1516*9a0e4156SSadaf Ebrahimi<details><summary> 示例,结合cs_errno使用 </summary>
1517*9a0e4156SSadaf Ebrahimi
1518*9a0e4156SSadaf Ebrahimi```cpp
1519*9a0e4156SSadaf Ebrahimi#include <iostream>
1520*9a0e4156SSadaf Ebrahimi#include <stdio.h>
1521*9a0e4156SSadaf Ebrahimi
1522*9a0e4156SSadaf Ebrahimi#include "capstone.h"
1523*9a0e4156SSadaf Ebrahimi#include "platform.h"
1524*9a0e4156SSadaf Ebrahimi
1525*9a0e4156SSadaf Ebrahimiusing namespace std;
1526*9a0e4156SSadaf Ebrahimi
1527*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00"
1528*9a0e4156SSadaf Ebrahimi
1529*9a0e4156SSadaf Ebrahimiint main(void)
1530*9a0e4156SSadaf Ebrahimi{
1531*9a0e4156SSadaf Ebrahimi	csh handle = 0;
1532*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
1533*9a0e4156SSadaf Ebrahimi	size_t count;
1534*9a0e4156SSadaf Ebrahimi
1535*9a0e4156SSadaf Ebrahimi	if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) {
1536*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to initialize engine!\n");
1537*9a0e4156SSadaf Ebrahimi		return -1;
1538*9a0e4156SSadaf Ebrahimi	}
1539*9a0e4156SSadaf Ebrahimi
1540*9a0e4156SSadaf Ebrahimi	cs_close(&handle);
1541*9a0e4156SSadaf Ebrahimi	std::cout << cs_strerror(cs_errno(handle));  //直接输出报错信息
1542*9a0e4156SSadaf Ebrahimi	return 0;
1543*9a0e4156SSadaf Ebrahimi}
1544*9a0e4156SSadaf Ebrahimi```
1545*9a0e4156SSadaf Ebrahimi
1546*9a0e4156SSadaf Ebrahimi</details>
1547*9a0e4156SSadaf Ebrahimi
1548*9a0e4156SSadaf Ebrahimi输出
1549*9a0e4156SSadaf Ebrahimi
1550*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/18.jpg)
1551*9a0e4156SSadaf Ebrahimi
1552*9a0e4156SSadaf Ebrahimi
1553*9a0e4156SSadaf Ebrahimi### cs_disasm
1554*9a0e4156SSadaf Ebrahimi
1555*9a0e4156SSadaf Ebrahimi```cpp
1556*9a0e4156SSadaf Ebrahimisize_t CAPSTONE_API cs_disasm(csh handle,
1557*9a0e4156SSadaf Ebrahimi		const uint8_t *code, size_t code_size,
1558*9a0e4156SSadaf Ebrahimi		uint64_t address,
1559*9a0e4156SSadaf Ebrahimi		size_t count,
1560*9a0e4156SSadaf Ebrahimi		cs_insn **insn);
1561*9a0e4156SSadaf Ebrahimi```
1562*9a0e4156SSadaf Ebrahimi
1563*9a0e4156SSadaf Ebrahimi给定缓冲区、大小、地址和编号,反编译机器码
1564*9a0e4156SSadaf Ebrahimi
1565*9a0e4156SSadaf EbrahimiAPI动态地分配内存来包含分解的指令,生成的指令将放在*insn中
1566*9a0e4156SSadaf Ebrahimi
1567*9a0e4156SSadaf Ebrahimi注意: 必须释放分配的内存,以避免内存泄漏。对于需要动态分配稀缺内存的系统(如OS内核或固件),API cs_disasm_iter()可能是比cs_disasm()更好的选择。原因是,使用cs_disasm()时,基于有限的可用内存,必须预先计算要分解多少条指令。
1568*9a0e4156SSadaf Ebrahimi
1569*9a0e4156SSadaf Ebrahimi```
1570*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
1571*9a0e4156SSadaf Ebrahimicode: 包含要反汇编的机器码的缓冲区。
1572*9a0e4156SSadaf Ebrahimicode_size:上面代码缓冲区的大小。
1573*9a0e4156SSadaf Ebrahimiaddress:给定原始代码缓冲区中的第一条指令的地址。
1574*9a0e4156SSadaf Ebrahimiinsn: 由这个API填写的指令数组。注意: insn将由这个函数分配,应该用cs_free () API释放
1575*9a0e4156SSadaf Ebrahimicount: 需要分解的指令数量,或输入0分解所有指令
1576*9a0e4156SSadaf Ebrahimireturn:成功反汇编指令的数量,如果该函数未能反汇编给定的代码,则为0,失败时,调用cs_errno()获取错误代码。
1577*9a0e4156SSadaf Ebrahimi```
1578*9a0e4156SSadaf Ebrahimi
1579*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
1580*9a0e4156SSadaf Ebrahimi
1581*9a0e4156SSadaf Ebrahimi```cpp
1582*9a0e4156SSadaf Ebrahimisize_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
1583*9a0e4156SSadaf Ebrahimi{
1584*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
1585*9a0e4156SSadaf Ebrahimi	MCInst mci;
1586*9a0e4156SSadaf Ebrahimi	uint16_t insn_size;
1587*9a0e4156SSadaf Ebrahimi	size_t c = 0, i;
1588*9a0e4156SSadaf Ebrahimi	unsigned int f = 0;	// 缓存中下一条指令的索引
1589*9a0e4156SSadaf Ebrahimi	cs_insn *insn_cache;	// 缓存反汇编后的指令
1590*9a0e4156SSadaf Ebrahimi	void *total = NULL;
1591*9a0e4156SSadaf Ebrahimi	size_t total_size = 0;	//所有insn的输出缓冲区的总大小
1592*9a0e4156SSadaf Ebrahimi	bool r;
1593*9a0e4156SSadaf Ebrahimi	void *tmp;
1594*9a0e4156SSadaf Ebrahimi	size_t skipdata_bytes;
1595*9a0e4156SSadaf Ebrahimi	uint64_t offset_org; // 保存缓冲区的所有原始信息
1596*9a0e4156SSadaf Ebrahimi	size_t size_org;
1597*9a0e4156SSadaf Ebrahimi	const uint8_t *buffer_org;
1598*9a0e4156SSadaf Ebrahimi	unsigned int cache_size = INSN_CACHE_SIZE;
1599*9a0e4156SSadaf Ebrahimi	size_t next_offset;
1600*9a0e4156SSadaf Ebrahimi
1601*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
1602*9a0e4156SSadaf Ebrahimi	if (!handle) {
1603*9a0e4156SSadaf Ebrahimi		// 修复方式:
1604*9a0e4156SSadaf Ebrahimi		// handle->errnum = CS_ERR_HANDLE;
1605*9a0e4156SSadaf Ebrahimi		return 0;
1606*9a0e4156SSadaf Ebrahimi	}
1607*9a0e4156SSadaf Ebrahimi
1608*9a0e4156SSadaf Ebrahimi	handle->errnum = CS_ERR_OK;
1609*9a0e4156SSadaf Ebrahimi
1610*9a0e4156SSadaf Ebrahimi	// 重设ARM架构的IT block
1611*9a0e4156SSadaf Ebrahimi	if (handle->arch == CS_ARCH_ARM)
1612*9a0e4156SSadaf Ebrahimi		handle->ITBlock.size = 0;
1613*9a0e4156SSadaf Ebrahimi
1614*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_USE_SYS_DYN_MEM
1615*9a0e4156SSadaf Ebrahimi	if (count > 0 && count <= INSN_CACHE_SIZE)
1616*9a0e4156SSadaf Ebrahimi		cache_size = (unsigned int) count;
1617*9a0e4156SSadaf Ebrahimi#endif
1618*9a0e4156SSadaf Ebrahimi
1619*9a0e4156SSadaf Ebrahimi	// 保存SKIPDATA原始偏移量
1620*9a0e4156SSadaf Ebrahimi	buffer_org = buffer;
1621*9a0e4156SSadaf Ebrahimi	offset_org = offset;
1622*9a0e4156SSadaf Ebrahimi	size_org = size;
1623*9a0e4156SSadaf Ebrahimi
1624*9a0e4156SSadaf Ebrahimi	total_size = sizeof(cs_insn) * cache_size;
1625*9a0e4156SSadaf Ebrahimi	total = cs_mem_malloc(total_size);
1626*9a0e4156SSadaf Ebrahimi	if (total == NULL) {
1627*9a0e4156SSadaf Ebrahimi		// 内存不足
1628*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_MEM;
1629*9a0e4156SSadaf Ebrahimi		return 0;
1630*9a0e4156SSadaf Ebrahimi	}
1631*9a0e4156SSadaf Ebrahimi
1632*9a0e4156SSadaf Ebrahimi	insn_cache = total;
1633*9a0e4156SSadaf Ebrahimi
1634*9a0e4156SSadaf Ebrahimi	while (size > 0) {
1635*9a0e4156SSadaf Ebrahimi		MCInst_Init(&mci);
1636*9a0e4156SSadaf Ebrahimi		mci.csh = handle;
1637*9a0e4156SSadaf Ebrahimi
1638*9a0e4156SSadaf Ebrahimi		mci.address = offset;
1639*9a0e4156SSadaf Ebrahimi
1640*9a0e4156SSadaf Ebrahimi		if (handle->detail) {
1641*9a0e4156SSadaf Ebrahimi			//给detail指针分配内存
1642*9a0e4156SSadaf Ebrahimi			insn_cache->detail = cs_mem_malloc(sizeof(cs_detail));
1643*9a0e4156SSadaf Ebrahimi		} else {
1644*9a0e4156SSadaf Ebrahimi			insn_cache->detail = NULL;
1645*9a0e4156SSadaf Ebrahimi		}
1646*9a0e4156SSadaf Ebrahimi
1647*9a0e4156SSadaf Ebrahimi		// 为non-detailed模式保存所有信息
1648*9a0e4156SSadaf Ebrahimi		mci.flat_insn = insn_cache;
1649*9a0e4156SSadaf Ebrahimi		mci.flat_insn->address = offset;
1650*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET
1651*9a0e4156SSadaf Ebrahimi		//mnemonic & op_str0填充
1652*9a0e4156SSadaf Ebrahimi		mci.flat_insn->mnemonic[0] = '\0';
1653*9a0e4156SSadaf Ebrahimi		mci.flat_insn->op_str[0] = '\0';
1654*9a0e4156SSadaf Ebrahimi#endif
1655*9a0e4156SSadaf Ebrahimi
1656*9a0e4156SSadaf Ebrahimi		r = handle->disasm(ud, buffer, size, &mci, &insn_size, offset, handle->getinsn_info);
1657*9a0e4156SSadaf Ebrahimi		if (r) {
1658*9a0e4156SSadaf Ebrahimi			SStream ss;
1659*9a0e4156SSadaf Ebrahimi			SStream_Init(&ss);
1660*9a0e4156SSadaf Ebrahimi
1661*9a0e4156SSadaf Ebrahimi			mci.flat_insn->size = insn_size;
1662*9a0e4156SSadaf Ebrahimi
1663*9a0e4156SSadaf Ebrahimi			//将内部指令操作码映射到公共insn ID
1664*9a0e4156SSadaf Ebrahimi			handle->insn_id(handle, insn_cache, mci.Opcode);
1665*9a0e4156SSadaf Ebrahimi
1666*9a0e4156SSadaf Ebrahimi			handle->printer(&mci, &ss, handle->printer_info);
1667*9a0e4156SSadaf Ebrahimi			fill_insn(handle, insn_cache, ss.buffer, &mci, handle->post_printer, buffer);
1668*9a0e4156SSadaf Ebrahimi
1669*9a0e4156SSadaf Ebrahimi			// 调整opcode (X86)
1670*9a0e4156SSadaf Ebrahimi			if (handle->arch == CS_ARCH_X86)
1671*9a0e4156SSadaf Ebrahimi				insn_cache->id += mci.popcode_adjust;
1672*9a0e4156SSadaf Ebrahimi
1673*9a0e4156SSadaf Ebrahimi			next_offset = insn_size;
1674*9a0e4156SSadaf Ebrahimi		} else	{
1675*9a0e4156SSadaf Ebrahimi			// 遇到中断指令
1676*9a0e4156SSadaf Ebrahimi
1677*9a0e4156SSadaf Ebrahimi			// 为detail指针释放内存
1678*9a0e4156SSadaf Ebrahimi			if (handle->detail) {
1679*9a0e4156SSadaf Ebrahimi				cs_mem_free(insn_cache->detail);
1680*9a0e4156SSadaf Ebrahimi			}
1681*9a0e4156SSadaf Ebrahimi
1682*9a0e4156SSadaf Ebrahimi			if (!handle->skipdata || handle->skipdata_size > size)
1683*9a0e4156SSadaf Ebrahimi				break;
1684*9a0e4156SSadaf Ebrahimi
1685*9a0e4156SSadaf Ebrahimi			if (handle->skipdata_setup.callback) {
1686*9a0e4156SSadaf Ebrahimi				skipdata_bytes = handle->skipdata_setup.callback(buffer_org, size_org,
1687*9a0e4156SSadaf Ebrahimi						(size_t)(offset - offset_org), handle->skipdata_setup.user_data);
1688*9a0e4156SSadaf Ebrahimi				if (skipdata_bytes > size)
1689*9a0e4156SSadaf Ebrahimi					break;
1690*9a0e4156SSadaf Ebrahimi
1691*9a0e4156SSadaf Ebrahimi				if (!skipdata_bytes)
1692*9a0e4156SSadaf Ebrahimi					break;
1693*9a0e4156SSadaf Ebrahimi			} else
1694*9a0e4156SSadaf Ebrahimi				skipdata_bytes = handle->skipdata_size;
1695*9a0e4156SSadaf Ebrahimi
1696*9a0e4156SSadaf Ebrahimi			insn_cache->id = 0;
1697*9a0e4156SSadaf Ebrahimi			insn_cache->address = offset;
1698*9a0e4156SSadaf Ebrahimi			insn_cache->size = (uint16_t)skipdata_bytes;
1699*9a0e4156SSadaf Ebrahimi			memcpy(insn_cache->bytes, buffer, skipdata_bytes);
1700*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET
1701*9a0e4156SSadaf Ebrahimi			insn_cache->mnemonic[0] = '\0';
1702*9a0e4156SSadaf Ebrahimi			insn_cache->op_str[0] = '\0';
1703*9a0e4156SSadaf Ebrahimi#else
1704*9a0e4156SSadaf Ebrahimi			strncpy(insn_cache->mnemonic, handle->skipdata_setup.mnemonic,
1705*9a0e4156SSadaf Ebrahimi					sizeof(insn_cache->mnemonic) - 1);
1706*9a0e4156SSadaf Ebrahimi			skipdata_opstr(insn_cache->op_str, buffer, skipdata_bytes);
1707*9a0e4156SSadaf Ebrahimi#endif
1708*9a0e4156SSadaf Ebrahimi			insn_cache->detail = NULL;
1709*9a0e4156SSadaf Ebrahimi
1710*9a0e4156SSadaf Ebrahimi			next_offset = skipdata_bytes;
1711*9a0e4156SSadaf Ebrahimi		}
1712*9a0e4156SSadaf Ebrahimi
1713*9a0e4156SSadaf Ebrahimi		// 一条新指令进入缓存
1714*9a0e4156SSadaf Ebrahimi		f++;
1715*9a0e4156SSadaf Ebrahimi
1716*9a0e4156SSadaf Ebrahimi		// 反汇编了一条指令
1717*9a0e4156SSadaf Ebrahimi		c++;
1718*9a0e4156SSadaf Ebrahimi		if (count > 0 && c == count)
1719*9a0e4156SSadaf Ebrahimi			break;
1720*9a0e4156SSadaf Ebrahimi
1721*9a0e4156SSadaf Ebrahimi		if (f == cache_size) {
1722*9a0e4156SSadaf Ebrahimi			cache_size = cache_size * 8 / 5;
1723*9a0e4156SSadaf Ebrahimi			total_size += (sizeof(cs_insn) * cache_size);
1724*9a0e4156SSadaf Ebrahimi			tmp = cs_mem_realloc(total, total_size);
1725*9a0e4156SSadaf Ebrahimi			if (tmp == NULL) {	//内存不足
1726*9a0e4156SSadaf Ebrahimi				if (handle->detail) {
1727*9a0e4156SSadaf Ebrahimi					insn_cache = (cs_insn *)total;
1728*9a0e4156SSadaf Ebrahimi					for (i = 0; i < c; i++, insn_cache++)
1729*9a0e4156SSadaf Ebrahimi						cs_mem_free(insn_cache->detail);
1730*9a0e4156SSadaf Ebrahimi				}
1731*9a0e4156SSadaf Ebrahimi
1732*9a0e4156SSadaf Ebrahimi				cs_mem_free(total);
1733*9a0e4156SSadaf Ebrahimi				*insn = NULL;
1734*9a0e4156SSadaf Ebrahimi				handle->errnum = CS_ERR_MEM;
1735*9a0e4156SSadaf Ebrahimi				return 0;
1736*9a0e4156SSadaf Ebrahimi			}
1737*9a0e4156SSadaf Ebrahimi
1738*9a0e4156SSadaf Ebrahimi			total = tmp;
1739*9a0e4156SSadaf Ebrahimi			//在最后一条指令之后继续填充缓存
1740*9a0e4156SSadaf Ebrahimi			insn_cache = (cs_insn *)((char *)total + sizeof(cs_insn) * c);
1741*9a0e4156SSadaf Ebrahimi
1742*9a0e4156SSadaf Ebrahimi			// 将f重置为0,从一开始就填入缓存
1743*9a0e4156SSadaf Ebrahimi			f = 0;
1744*9a0e4156SSadaf Ebrahimi		} else
1745*9a0e4156SSadaf Ebrahimi			insn_cache++;
1746*9a0e4156SSadaf Ebrahimi
1747*9a0e4156SSadaf Ebrahimi		buffer += next_offset;
1748*9a0e4156SSadaf Ebrahimi		size -= next_offset;
1749*9a0e4156SSadaf Ebrahimi		offset += next_offset;
1750*9a0e4156SSadaf Ebrahimi	}
1751*9a0e4156SSadaf Ebrahimi
1752*9a0e4156SSadaf Ebrahimi	if (!c) {
1753*9a0e4156SSadaf Ebrahimi		//未反汇编任何指令
1754*9a0e4156SSadaf Ebrahimi		cs_mem_free(total);
1755*9a0e4156SSadaf Ebrahimi		total = NULL;
1756*9a0e4156SSadaf Ebrahimi	} else if (f != cache_size) {
1757*9a0e4156SSadaf Ebrahimi		// 没有完全使用最后一个缓存,缩小大小
1758*9a0e4156SSadaf Ebrahimi		tmp = cs_mem_realloc(total, total_size - (cache_size - f) * sizeof(*insn_cache));
1759*9a0e4156SSadaf Ebrahimi		if (tmp == NULL) {	// 内存不足
1760*9a0e4156SSadaf Ebrahimi			// 释放所有detail指针
1761*9a0e4156SSadaf Ebrahimi			if (handle->detail) {
1762*9a0e4156SSadaf Ebrahimi				insn_cache = (cs_insn *)total;
1763*9a0e4156SSadaf Ebrahimi				for (i = 0; i < c; i++, insn_cache++)
1764*9a0e4156SSadaf Ebrahimi					cs_mem_free(insn_cache->detail);
1765*9a0e4156SSadaf Ebrahimi			}
1766*9a0e4156SSadaf Ebrahimi
1767*9a0e4156SSadaf Ebrahimi			cs_mem_free(total);
1768*9a0e4156SSadaf Ebrahimi			*insn = NULL;
1769*9a0e4156SSadaf Ebrahimi
1770*9a0e4156SSadaf Ebrahimi			handle->errnum = CS_ERR_MEM;
1771*9a0e4156SSadaf Ebrahimi			return 0;
1772*9a0e4156SSadaf Ebrahimi		}
1773*9a0e4156SSadaf Ebrahimi
1774*9a0e4156SSadaf Ebrahimi		total = tmp;
1775*9a0e4156SSadaf Ebrahimi	}
1776*9a0e4156SSadaf Ebrahimi
1777*9a0e4156SSadaf Ebrahimi	*insn = total;
1778*9a0e4156SSadaf Ebrahimi
1779*9a0e4156SSadaf Ebrahimi	return c;
1780*9a0e4156SSadaf Ebrahimi}
1781*9a0e4156SSadaf Ebrahimi```
1782*9a0e4156SSadaf Ebrahimi
1783*9a0e4156SSadaf Ebrahimi</details>
1784*9a0e4156SSadaf Ebrahimi
1785*9a0e4156SSadaf Ebrahimi
1786*9a0e4156SSadaf Ebrahimi<details><summary> 示例,x86_64 </summary>
1787*9a0e4156SSadaf Ebrahimi
1788*9a0e4156SSadaf Ebrahimi```cpp
1789*9a0e4156SSadaf Ebrahimi#include <iostream>
1790*9a0e4156SSadaf Ebrahimi#include <stdio.h>
1791*9a0e4156SSadaf Ebrahimi
1792*9a0e4156SSadaf Ebrahimi#include "capstone.h"
1793*9a0e4156SSadaf Ebrahimi#include "platform.h"
1794*9a0e4156SSadaf Ebrahimi
1795*9a0e4156SSadaf Ebrahimiusing namespace std;
1796*9a0e4156SSadaf Ebrahimi
1797*9a0e4156SSadaf Ebrahimi#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
1798*9a0e4156SSadaf Ebrahimi
1799*9a0e4156SSadaf Ebrahimiint main(void)
1800*9a0e4156SSadaf Ebrahimi{
1801*9a0e4156SSadaf Ebrahimi	csh handle = 0;
1802*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
1803*9a0e4156SSadaf Ebrahimi	size_t count;
1804*9a0e4156SSadaf Ebrahimi
1805*9a0e4156SSadaf Ebrahimi	if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) {
1806*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to initialize engine!\n");
1807*9a0e4156SSadaf Ebrahimi		return -1;
1808*9a0e4156SSadaf Ebrahimi	}
1809*9a0e4156SSadaf Ebrahimi
1810*9a0e4156SSadaf Ebrahimi	count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn);   //所有指令,基址0x1000,放入insn
1811*9a0e4156SSadaf Ebrahimi	if (count) {
1812*9a0e4156SSadaf Ebrahimi		size_t j;
1813*9a0e4156SSadaf Ebrahimi
1814*9a0e4156SSadaf Ebrahimi		for (j = 0; j < count; j++) {
1815*9a0e4156SSadaf Ebrahimi			printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
1816*9a0e4156SSadaf Ebrahimi		}
1817*9a0e4156SSadaf Ebrahimi
1818*9a0e4156SSadaf Ebrahimi		cs_free(insn, count);
1819*9a0e4156SSadaf Ebrahimi	}
1820*9a0e4156SSadaf Ebrahimi	else
1821*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to disassemble given code!\n");
1822*9a0e4156SSadaf Ebrahimi
1823*9a0e4156SSadaf Ebrahimi	cs_close(&handle);
1824*9a0e4156SSadaf Ebrahimi
1825*9a0e4156SSadaf Ebrahimi	return 0;
1826*9a0e4156SSadaf Ebrahimi}
1827*9a0e4156SSadaf Ebrahimi```
1828*9a0e4156SSadaf Ebrahimi
1829*9a0e4156SSadaf Ebrahimi</details>
1830*9a0e4156SSadaf Ebrahimi
1831*9a0e4156SSadaf Ebrahimi输出
1832*9a0e4156SSadaf Ebrahimi
1833*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/19.jpg)
1834*9a0e4156SSadaf Ebrahimi
1835*9a0e4156SSadaf Ebrahimi
1836*9a0e4156SSadaf Ebrahimi### cs_free
1837*9a0e4156SSadaf Ebrahimi
1838*9a0e4156SSadaf Ebrahimi`void CAPSTONE_API cs_free(cs_insn *insn, size_t count);`
1839*9a0e4156SSadaf Ebrahimi
1840*9a0e4156SSadaf Ebrahimi释放被 cs_malloc() 或 cs_disasm() 分配的内存(insn参数)
1841*9a0e4156SSadaf Ebrahimi
1842*9a0e4156SSadaf Ebrahimi```
1843*9a0e4156SSadaf Ebrahimiinsn: 由cs_disasm()或cs_malloc()中的@insn参数返回的指针
1844*9a0e4156SSadaf Ebrahimicount: 赋值由cs_disasm()返回的cs_insn结构的数量,或赋值为1表示由cs_malloc()分配给空闲内存的数量
1845*9a0e4156SSadaf Ebrahimi```
1846*9a0e4156SSadaf Ebrahimi
1847*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
1848*9a0e4156SSadaf Ebrahimi
1849*9a0e4156SSadaf Ebrahimi```cpp
1850*9a0e4156SSadaf Ebrahimivoid CAPSTONE_API cs_free(cs_insn *insn, size_t count)
1851*9a0e4156SSadaf Ebrahimi{
1852*9a0e4156SSadaf Ebrahimi	size_t i;
1853*9a0e4156SSadaf Ebrahimi
1854*9a0e4156SSadaf Ebrahimi	// free 所有 detail 指针
1855*9a0e4156SSadaf Ebrahimi	for (i = 0; i < count; i++)
1856*9a0e4156SSadaf Ebrahimi		cs_mem_free(insn[i].detail);
1857*9a0e4156SSadaf Ebrahimi
1858*9a0e4156SSadaf Ebrahimi	cs_mem_free(insn);
1859*9a0e4156SSadaf Ebrahimi}
1860*9a0e4156SSadaf Ebrahimi```
1861*9a0e4156SSadaf Ebrahimi
1862*9a0e4156SSadaf Ebrahimi直接调用cs_mem_free,也就是默认的free
1863*9a0e4156SSadaf Ebrahimi
1864*9a0e4156SSadaf Ebrahimi</details>
1865*9a0e4156SSadaf Ebrahimi
1866*9a0e4156SSadaf Ebrahimi
1867*9a0e4156SSadaf Ebrahimi<details><summary> 示例(释放cs_disasm申请的内存) </summary>
1868*9a0e4156SSadaf Ebrahimi
1869*9a0e4156SSadaf Ebrahimi```cpp
1870*9a0e4156SSadaf Ebrahimi	count = cs_disasm(handle, (unsigned char*)CODE, sizeof(CODE) - 1, 0x1000, 0, &insn);           //计数由cs_disasm申请的内存
1871*9a0e4156SSadaf Ebrahimi	if (count) {
1872*9a0e4156SSadaf Ebrahimi		size_t j;
1873*9a0e4156SSadaf Ebrahimi
1874*9a0e4156SSadaf Ebrahimi		for (j = 0; j < count; j++) {
1875*9a0e4156SSadaf Ebrahimi			printf("0x%""Ix"":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
1876*9a0e4156SSadaf Ebrahimi		}
1877*9a0e4156SSadaf Ebrahimi
1878*9a0e4156SSadaf Ebrahimi		cs_free(insn, count);   //循环依次释放每条insn的内存
1879*9a0e4156SSadaf Ebrahimi	}
1880*9a0e4156SSadaf Ebrahimi```
1881*9a0e4156SSadaf Ebrahimi
1882*9a0e4156SSadaf Ebrahimi</details>
1883*9a0e4156SSadaf Ebrahimi
1884*9a0e4156SSadaf Ebrahimi
1885*9a0e4156SSadaf Ebrahimi### cs_malloc
1886*9a0e4156SSadaf Ebrahimi
1887*9a0e4156SSadaf Ebrahimi`cs_insn * CAPSTONE_API cs_malloc(csh handle);`
1888*9a0e4156SSadaf Ebrahimi
1889*9a0e4156SSadaf Ebrahimi被用于在API cs_disasm_iter()中为一条指令分配内存
1890*9a0e4156SSadaf Ebrahimi
1891*9a0e4156SSadaf Ebrahimi```
1892*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
1893*9a0e4156SSadaf Ebrahimi```
1894*9a0e4156SSadaf Ebrahimi
1895*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
1896*9a0e4156SSadaf Ebrahimi
1897*9a0e4156SSadaf Ebrahimi```cpp
1898*9a0e4156SSadaf Ebrahimics_insn * CAPSTONE_API cs_malloc(csh ud)
1899*9a0e4156SSadaf Ebrahimi{
1900*9a0e4156SSadaf Ebrahimi	cs_insn *insn;
1901*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
1902*9a0e4156SSadaf Ebrahimi
1903*9a0e4156SSadaf Ebrahimi	insn = cs_mem_malloc(sizeof(cs_insn));
1904*9a0e4156SSadaf Ebrahimi	if (!insn) {
1905*9a0e4156SSadaf Ebrahimi		// insufficient memory
1906*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_MEM;
1907*9a0e4156SSadaf Ebrahimi		return NULL;
1908*9a0e4156SSadaf Ebrahimi	} else {
1909*9a0e4156SSadaf Ebrahimi		if (handle->detail) {
1910*9a0e4156SSadaf Ebrahimi			// allocate memory for @detail pointer
1911*9a0e4156SSadaf Ebrahimi			insn->detail = cs_mem_malloc(sizeof(cs_detail));
1912*9a0e4156SSadaf Ebrahimi			if (insn->detail == NULL) {	// insufficient memory
1913*9a0e4156SSadaf Ebrahimi				cs_mem_free(insn);
1914*9a0e4156SSadaf Ebrahimi				handle->errnum = CS_ERR_MEM;
1915*9a0e4156SSadaf Ebrahimi				return NULL;
1916*9a0e4156SSadaf Ebrahimi			}
1917*9a0e4156SSadaf Ebrahimi		} else
1918*9a0e4156SSadaf Ebrahimi			insn->detail = NULL;
1919*9a0e4156SSadaf Ebrahimi	}
1920*9a0e4156SSadaf Ebrahimi
1921*9a0e4156SSadaf Ebrahimi	return insn;
1922*9a0e4156SSadaf Ebrahimi}
1923*9a0e4156SSadaf Ebrahimi```
1924*9a0e4156SSadaf Ebrahimi
1925*9a0e4156SSadaf Ebrahimi</details>
1926*9a0e4156SSadaf Ebrahimi
1927*9a0e4156SSadaf Ebrahimi当这条指令所占的内存不再使用时,使用cs_free(insn, 1)释放,示例在下面cs_disasm_iter处
1928*9a0e4156SSadaf Ebrahimi
1929*9a0e4156SSadaf Ebrahimi
1930*9a0e4156SSadaf Ebrahimi### cs_disasm_iter
1931*9a0e4156SSadaf Ebrahimi
1932*9a0e4156SSadaf Ebrahimi```cpp
1933*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_disasm_iter(csh handle,
1934*9a0e4156SSadaf Ebrahimi	const uint8_t **code, size_t *size,
1935*9a0e4156SSadaf Ebrahimi	uint64_t *address, cs_insn *insn);
1936*9a0e4156SSadaf Ebrahimi```
1937*9a0e4156SSadaf Ebrahimi
1938*9a0e4156SSadaf Ebrahimi给定buff、大小、地址和要解码的指令数,更快速的反汇编机器码,
1939*9a0e4156SSadaf Ebrahimi这个API将生成的指令放入insn中的给定的缓存中。
1940*9a0e4156SSadaf Ebrahimi
1941*9a0e4156SSadaf Ebrahimi注意1: 此API将更新code、size和address以指向输入缓冲区中的下一条指令。所以,虽然每次反汇编一条指令可以使用cs_disasm(count=1)来实现,但一些基准测试显示,在循环中使用cs_disasm_iter()可以方便地快速迭代所有指令,在随机输入时可以快30%。
1942*9a0e4156SSadaf Ebrahimi
1943*9a0e4156SSadaf Ebrahimi注意2:可以使用cs_malloc()创建insn中的缓存。
1944*9a0e4156SSadaf Ebrahimi
1945*9a0e4156SSadaf Ebrahimi注意3:对于动态分配内存可能产生内存不足的系统(比如OS内核或固件),建议使用cs_disasm()这个API, 因为cs_disasm()是根据要分解的指令的数量来分配内存。
1946*9a0e4156SSadaf Ebrahimi
1947*9a0e4156SSadaf Ebrahimi```
1948*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
1949*9a0e4156SSadaf Ebrahimicode: 要反汇编的机器码所在的缓冲区
1950*9a0e4156SSadaf Ebrahimisize: 机器码缓冲区的大小
1951*9a0e4156SSadaf Ebrahimiaddress: 所给机器码缓冲区中第一个insn的地址
1952*9a0e4156SSadaf Ebrahimiinsn: 指向这个API要填充的指令的指针。
1953*9a0e4156SSadaf Ebrahimireturn:如果这个API成功反汇编了一条指令返回true,否则将返回false。
1954*9a0e4156SSadaf Ebrahimi```
1955*9a0e4156SSadaf Ebrahimi
1956*9a0e4156SSadaf Ebrahimi失败时,调用cs_errno()获取错误代码。
1957*9a0e4156SSadaf Ebrahimi
1958*9a0e4156SSadaf Ebrahimi<details><summary> 代码实现,在cs_disasm基础上使用动态内存分配 </summary>
1959*9a0e4156SSadaf Ebrahimi
1960*9a0e4156SSadaf Ebrahimi```cpp
1961*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_disasm_iter(csh ud, const uint8_t **code, size_t *size,
1962*9a0e4156SSadaf Ebrahimi		uint64_t *address, cs_insn *insn)
1963*9a0e4156SSadaf Ebrahimi{
1964*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
1965*9a0e4156SSadaf Ebrahimi	uint16_t insn_size;
1966*9a0e4156SSadaf Ebrahimi	MCInst mci;
1967*9a0e4156SSadaf Ebrahimi	bool r;
1968*9a0e4156SSadaf Ebrahimi
1969*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
1970*9a0e4156SSadaf Ebrahimi	if (!handle) {
1971*9a0e4156SSadaf Ebrahimi		return false;
1972*9a0e4156SSadaf Ebrahimi	}
1973*9a0e4156SSadaf Ebrahimi
1974*9a0e4156SSadaf Ebrahimi	handle->errnum = CS_ERR_OK;
1975*9a0e4156SSadaf Ebrahimi
1976*9a0e4156SSadaf Ebrahimi	MCInst_Init(&mci);
1977*9a0e4156SSadaf Ebrahimi	mci.csh = handle;
1978*9a0e4156SSadaf Ebrahimi
1979*9a0e4156SSadaf Ebrahimi	mci.address = *address;
1980*9a0e4156SSadaf Ebrahimi
1981*9a0e4156SSadaf Ebrahimi	// 为无detail模式保存相关信息
1982*9a0e4156SSadaf Ebrahimi	mci.flat_insn = insn;
1983*9a0e4156SSadaf Ebrahimi	mci.flat_insn->address = *address;
1984*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET
1985*9a0e4156SSadaf Ebrahimi	mci.flat_insn->mnemonic[0] = '\0';
1986*9a0e4156SSadaf Ebrahimi	mci.flat_insn->op_str[0] = '\0';
1987*9a0e4156SSadaf Ebrahimi#endif
1988*9a0e4156SSadaf Ebrahimi
1989*9a0e4156SSadaf Ebrahimi	r = handle->disasm(ud, *code, *size, &mci, &insn_size, *address, handle->getinsn_info);
1990*9a0e4156SSadaf Ebrahimi	if (r) {
1991*9a0e4156SSadaf Ebrahimi		SStream ss;
1992*9a0e4156SSadaf Ebrahimi		SStream_Init(&ss);
1993*9a0e4156SSadaf Ebrahimi
1994*9a0e4156SSadaf Ebrahimi		mci.flat_insn->size = insn_size;
1995*9a0e4156SSadaf Ebrahimi
1996*9a0e4156SSadaf Ebrahimi		// 将内部指令操作码映射到公共insn ID
1997*9a0e4156SSadaf Ebrahimi		handle->insn_id(handle, insn, mci.Opcode);
1998*9a0e4156SSadaf Ebrahimi
1999*9a0e4156SSadaf Ebrahimi		handle->printer(&mci, &ss, handle->printer_info);
2000*9a0e4156SSadaf Ebrahimi
2001*9a0e4156SSadaf Ebrahimi		fill_insn(handle, insn, ss.buffer, &mci, handle->post_printer, *code);
2002*9a0e4156SSadaf Ebrahimi
2003*9a0e4156SSadaf Ebrahimi		// 调整伪操作码(X86)
2004*9a0e4156SSadaf Ebrahimi		if (handle->arch == CS_ARCH_X86)
2005*9a0e4156SSadaf Ebrahimi			insn->id += mci.popcode_adjust;
2006*9a0e4156SSadaf Ebrahimi
2007*9a0e4156SSadaf Ebrahimi		*code += insn_size;
2008*9a0e4156SSadaf Ebrahimi		*size -= insn_size;
2009*9a0e4156SSadaf Ebrahimi		*address += insn_size;
2010*9a0e4156SSadaf Ebrahimi	} else { 	// 遇到中断指令
2011*9a0e4156SSadaf Ebrahimi		size_t skipdata_bytes;
2012*9a0e4156SSadaf Ebrahimi
2013*9a0e4156SSadaf Ebrahimi		// 如果没有跳过数据的请求,或者剩余数据太小,则退出
2014*9a0e4156SSadaf Ebrahimi		if (!handle->skipdata || handle->skipdata_size > *size)
2015*9a0e4156SSadaf Ebrahimi			return false;
2016*9a0e4156SSadaf Ebrahimi
2017*9a0e4156SSadaf Ebrahimi		if (handle->skipdata_setup.callback) {
2018*9a0e4156SSadaf Ebrahimi			skipdata_bytes = handle->skipdata_setup.callback(*code, *size,
2019*9a0e4156SSadaf Ebrahimi					0, handle->skipdata_setup.user_data);
2020*9a0e4156SSadaf Ebrahimi			if (skipdata_bytes > *size)
2021*9a0e4156SSadaf Ebrahimi				// 剩余数据太小
2022*9a0e4156SSadaf Ebrahimi				return false;
2023*9a0e4156SSadaf Ebrahimi
2024*9a0e4156SSadaf Ebrahimi			if (!skipdata_bytes)
2025*9a0e4156SSadaf Ebrahimi				return false;
2026*9a0e4156SSadaf Ebrahimi		} else
2027*9a0e4156SSadaf Ebrahimi			skipdata_bytes = handle->skipdata_size;
2028*9a0e4156SSadaf Ebrahimi
2029*9a0e4156SSadaf Ebrahimi		// 基于架构和模式跳过一些数据
2030*9a0e4156SSadaf Ebrahimi		insn->id = 0;	// 此“数据”指令的ID无效
2031*9a0e4156SSadaf Ebrahimi		insn->address = *address;
2032*9a0e4156SSadaf Ebrahimi		insn->size = (uint16_t)skipdata_bytes;
2033*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET
2034*9a0e4156SSadaf Ebrahimi		insn->mnemonic[0] = '\0';
2035*9a0e4156SSadaf Ebrahimi		insn->op_str[0] = '\0';
2036*9a0e4156SSadaf Ebrahimi#else
2037*9a0e4156SSadaf Ebrahimi		memcpy(insn->bytes, *code, skipdata_bytes);
2038*9a0e4156SSadaf Ebrahimi		strncpy(insn->mnemonic, handle->skipdata_setup.mnemonic,
2039*9a0e4156SSadaf Ebrahimi				sizeof(insn->mnemonic) - 1);
2040*9a0e4156SSadaf Ebrahimi		skipdata_opstr(insn->op_str, *code, skipdata_bytes);
2041*9a0e4156SSadaf Ebrahimi#endif
2042*9a0e4156SSadaf Ebrahimi
2043*9a0e4156SSadaf Ebrahimi		*code += skipdata_bytes;
2044*9a0e4156SSadaf Ebrahimi		*size -= skipdata_bytes;
2045*9a0e4156SSadaf Ebrahimi		*address += skipdata_bytes;
2046*9a0e4156SSadaf Ebrahimi	}
2047*9a0e4156SSadaf Ebrahimi
2048*9a0e4156SSadaf Ebrahimi	return true;
2049*9a0e4156SSadaf Ebrahimi}
2050*9a0e4156SSadaf Ebrahimi```
2051*9a0e4156SSadaf Ebrahimi
2052*9a0e4156SSadaf Ebrahimi</details>
2053*9a0e4156SSadaf Ebrahimi
2054*9a0e4156SSadaf Ebrahimi
2055*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary>
2056*9a0e4156SSadaf Ebrahimi
2057*9a0e4156SSadaf Ebrahimi```cpp
2058*9a0e4156SSadaf Ebrahimi#include <iostream>
2059*9a0e4156SSadaf Ebrahimi#include <stdio.h>
2060*9a0e4156SSadaf Ebrahimi
2061*9a0e4156SSadaf Ebrahimi#include "capstone.h"
2062*9a0e4156SSadaf Ebrahimi#include "platform.h"
2063*9a0e4156SSadaf Ebrahimi
2064*9a0e4156SSadaf Ebrahimiusing namespace std;
2065*9a0e4156SSadaf Ebrahimi
2066*9a0e4156SSadaf Ebrahimistruct platform {
2067*9a0e4156SSadaf Ebrahimi	cs_arch arch;
2068*9a0e4156SSadaf Ebrahimi	cs_mode mode;
2069*9a0e4156SSadaf Ebrahimi	unsigned char* code;
2070*9a0e4156SSadaf Ebrahimi	size_t size;
2071*9a0e4156SSadaf Ebrahimi	const char* comment;
2072*9a0e4156SSadaf Ebrahimi	cs_opt_type opt_type;
2073*9a0e4156SSadaf Ebrahimi	cs_opt_value opt_value;
2074*9a0e4156SSadaf Ebrahimi};
2075*9a0e4156SSadaf Ebrahimi
2076*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len)
2077*9a0e4156SSadaf Ebrahimi{
2078*9a0e4156SSadaf Ebrahimi	unsigned char* c;
2079*9a0e4156SSadaf Ebrahimi
2080*9a0e4156SSadaf Ebrahimi	printf("Code: ");
2081*9a0e4156SSadaf Ebrahimi	for (c = str; c < str + len; c++) {
2082*9a0e4156SSadaf Ebrahimi		printf("0x%02x ", *c & 0xff);
2083*9a0e4156SSadaf Ebrahimi	}
2084*9a0e4156SSadaf Ebrahimi	printf("\n");
2085*9a0e4156SSadaf Ebrahimi}
2086*9a0e4156SSadaf Ebrahimi
2087*9a0e4156SSadaf Ebrahimistatic void test()
2088*9a0e4156SSadaf Ebrahimi{
2089*9a0e4156SSadaf Ebrahimi#define X86_CODE16 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
2090*9a0e4156SSadaf Ebrahimi#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
2091*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00"
2092*9a0e4156SSadaf Ebrahimi
2093*9a0e4156SSadaf Ebrahimi	struct platform platforms[4] = {     //架构及模式
2094*9a0e4156SSadaf Ebrahimi		{
2095*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
2096*9a0e4156SSadaf Ebrahimi			CS_MODE_16,
2097*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE16,
2098*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE32) - 1,
2099*9a0e4156SSadaf Ebrahimi			"X86 16bit (Intel syntax)"
2100*9a0e4156SSadaf Ebrahimi		},
2101*9a0e4156SSadaf Ebrahimi		{
2102*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
2103*9a0e4156SSadaf Ebrahimi			CS_MODE_32,
2104*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE32,
2105*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE32) - 1,
2106*9a0e4156SSadaf Ebrahimi			"X86 32bit (ATT syntax)",
2107*9a0e4156SSadaf Ebrahimi			CS_OPT_SYNTAX,
2108*9a0e4156SSadaf Ebrahimi			CS_OPT_SYNTAX_ATT,
2109*9a0e4156SSadaf Ebrahimi		},
2110*9a0e4156SSadaf Ebrahimi		{
2111*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
2112*9a0e4156SSadaf Ebrahimi			CS_MODE_32,
2113*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE32,
2114*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE32) - 1,
2115*9a0e4156SSadaf Ebrahimi			"X86 32 (Intel syntax)"
2116*9a0e4156SSadaf Ebrahimi		},
2117*9a0e4156SSadaf Ebrahimi		{
2118*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
2119*9a0e4156SSadaf Ebrahimi			CS_MODE_64,
2120*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE64,
2121*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE64) - 1,
2122*9a0e4156SSadaf Ebrahimi			"X86 64 (Intel syntax)"
2123*9a0e4156SSadaf Ebrahimi		},
2124*9a0e4156SSadaf Ebrahimi
2125*9a0e4156SSadaf Ebrahimi	csh handle;
2126*9a0e4156SSadaf Ebrahimi	uint64_t address;
2127*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
2128*9a0e4156SSadaf Ebrahimi	cs_detail* detail;
2129*9a0e4156SSadaf Ebrahimi	int i;
2130*9a0e4156SSadaf Ebrahimi	cs_err err;
2131*9a0e4156SSadaf Ebrahimi	const uint8_t* code;
2132*9a0e4156SSadaf Ebrahimi	size_t size;
2133*9a0e4156SSadaf Ebrahimi
2134*9a0e4156SSadaf Ebrahimi	for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
2135*9a0e4156SSadaf Ebrahimi		printf("****************\n");
2136*9a0e4156SSadaf Ebrahimi		printf("Platform: %s\n", platforms[i].comment);
2137*9a0e4156SSadaf Ebrahimi		err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
2138*9a0e4156SSadaf Ebrahimi		if (err) {
2139*9a0e4156SSadaf Ebrahimi			printf("Failed on cs_open() with error returned: %u\n", err);
2140*9a0e4156SSadaf Ebrahimi			abort();
2141*9a0e4156SSadaf Ebrahimi		}
2142*9a0e4156SSadaf Ebrahimi
2143*9a0e4156SSadaf Ebrahimi		if (platforms[i].opt_type)
2144*9a0e4156SSadaf Ebrahimi			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
2145*9a0e4156SSadaf Ebrahimi
2146*9a0e4156SSadaf Ebrahimi		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
2147*9a0e4156SSadaf Ebrahimi
2148*9a0e4156SSadaf Ebrahimi		// 为cs_disasm_iter()分配内存
2149*9a0e4156SSadaf Ebrahimi		insn = cs_malloc(handle);
2150*9a0e4156SSadaf Ebrahimi
2151*9a0e4156SSadaf Ebrahimi		print_string_hex(platforms[i].code, platforms[i].size);   //原机器码
2152*9a0e4156SSadaf Ebrahimi		printf("Disasm:\n");
2153*9a0e4156SSadaf Ebrahimi
2154*9a0e4156SSadaf Ebrahimi		address = 0x1000;
2155*9a0e4156SSadaf Ebrahimi		code = platforms[i].code;
2156*9a0e4156SSadaf Ebrahimi		size = platforms[i].size;
2157*9a0e4156SSadaf Ebrahimi		while (cs_disasm_iter(handle, &code, &size, &address, insn)) {   //cs_disasm_iter反汇编
2158*9a0e4156SSadaf Ebrahimi			int n;
2159*9a0e4156SSadaf Ebrahimi
2160*9a0e4156SSadaf Ebrahimi			printf("0x%" PRIx64 ":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n",
2161*9a0e4156SSadaf Ebrahimi				insn->address, insn->mnemonic, insn->op_str,
2162*9a0e4156SSadaf Ebrahimi				insn->id, cs_insn_name(handle, insn->id));
2163*9a0e4156SSadaf Ebrahimi
2164*9a0e4156SSadaf Ebrahimi			// 打印此指令使用的隐式寄存器
2165*9a0e4156SSadaf Ebrahimi			detail = insn->detail;
2166*9a0e4156SSadaf Ebrahimi
2167*9a0e4156SSadaf Ebrahimi			if (detail->regs_read_count > 0) {
2168*9a0e4156SSadaf Ebrahimi				printf("\tImplicit registers read: ");
2169*9a0e4156SSadaf Ebrahimi				for (n = 0; n < detail->regs_read_count; n++) {
2170*9a0e4156SSadaf Ebrahimi					printf("%s ", cs_reg_name(handle, detail->regs_read[n]));
2171*9a0e4156SSadaf Ebrahimi				}
2172*9a0e4156SSadaf Ebrahimi				printf("\n");
2173*9a0e4156SSadaf Ebrahimi			}
2174*9a0e4156SSadaf Ebrahimi
2175*9a0e4156SSadaf Ebrahimi			// 打印此指令修改的隐式寄存器
2176*9a0e4156SSadaf Ebrahimi			if (detail->regs_write_count > 0) {
2177*9a0e4156SSadaf Ebrahimi				printf("\tImplicit registers modified: ");
2178*9a0e4156SSadaf Ebrahimi				for (n = 0; n < detail->regs_write_count; n++) {
2179*9a0e4156SSadaf Ebrahimi					printf("%s ", cs_reg_name(handle, detail->regs_write[n]));
2180*9a0e4156SSadaf Ebrahimi				}
2181*9a0e4156SSadaf Ebrahimi				printf("\n");
2182*9a0e4156SSadaf Ebrahimi			}
2183*9a0e4156SSadaf Ebrahimi
2184*9a0e4156SSadaf Ebrahimi			// 打印此指令所属指令集
2185*9a0e4156SSadaf Ebrahimi			if (detail->groups_count > 0) {
2186*9a0e4156SSadaf Ebrahimi				printf("\tThis instruction belongs to groups: ");
2187*9a0e4156SSadaf Ebrahimi				for (n = 0; n < detail->groups_count; n++) {
2188*9a0e4156SSadaf Ebrahimi					printf("%s ", cs_group_name(handle, detail->groups[n]));
2189*9a0e4156SSadaf Ebrahimi				}
2190*9a0e4156SSadaf Ebrahimi				printf("\n");
2191*9a0e4156SSadaf Ebrahimi			}
2192*9a0e4156SSadaf Ebrahimi		}
2193*9a0e4156SSadaf Ebrahimi
2194*9a0e4156SSadaf Ebrahimi		printf("\n");
2195*9a0e4156SSadaf Ebrahimi
2196*9a0e4156SSadaf Ebrahimi		// 释放cs_malloc()分配的内存
2197*9a0e4156SSadaf Ebrahimi		cs_free(insn, 1);
2198*9a0e4156SSadaf Ebrahimi
2199*9a0e4156SSadaf Ebrahimi		cs_close(&handle);
2200*9a0e4156SSadaf Ebrahimi	}
2201*9a0e4156SSadaf Ebrahimi}
2202*9a0e4156SSadaf Ebrahimi
2203*9a0e4156SSadaf Ebrahimiint main()
2204*9a0e4156SSadaf Ebrahimi{
2205*9a0e4156SSadaf Ebrahimi	test();
2206*9a0e4156SSadaf Ebrahimi
2207*9a0e4156SSadaf Ebrahimi	return 0;
2208*9a0e4156SSadaf Ebrahimi}
2209*9a0e4156SSadaf Ebrahimi```
2210*9a0e4156SSadaf Ebrahimi
2211*9a0e4156SSadaf Ebrahimi</details>
2212*9a0e4156SSadaf Ebrahimi
2213*9a0e4156SSadaf Ebrahimi输出
2214*9a0e4156SSadaf Ebrahimi
2215*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/20.jpg)
2216*9a0e4156SSadaf Ebrahimi
2217*9a0e4156SSadaf Ebrahimi
2218*9a0e4156SSadaf Ebrahimi### cs_reg_name
2219*9a0e4156SSadaf Ebrahimi
2220*9a0e4156SSadaf Ebrahimi`const char * CAPSTONE_API cs_reg_name(csh handle, unsigned int reg_id);`
2221*9a0e4156SSadaf Ebrahimi
2222*9a0e4156SSadaf Ebrahimi获取寄存器的名字(string类型)
2223*9a0e4156SSadaf Ebrahimi寄存器id可在相关架构的头文件(建立项目时复制到项目文件夹的那些头文件)内找到
2224*9a0e4156SSadaf Ebrahimi
2225*9a0e4156SSadaf Ebrahimi注意: 当处于diet模式时此API不可用,因为引擎不会存储寄存器名
2226*9a0e4156SSadaf Ebrahimi
2227*9a0e4156SSadaf Ebrahimi```
2228*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
2229*9a0e4156SSadaf Ebrahimireg_id: 寄存器id
2230*9a0e4156SSadaf Ebrahimireturn: 寄存器的字符名, 如果reg_id不可用返回NULL
2231*9a0e4156SSadaf Ebrahimi```
2232*9a0e4156SSadaf Ebrahimi
2233*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
2234*9a0e4156SSadaf Ebrahimi
2235*9a0e4156SSadaf Ebrahimi```cpp
2236*9a0e4156SSadaf Ebrahimiconst char * CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
2237*9a0e4156SSadaf Ebrahimi{
2238*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
2239*9a0e4156SSadaf Ebrahimi
2240*9a0e4156SSadaf Ebrahimi	if (!handle || handle->reg_name == NULL) {
2241*9a0e4156SSadaf Ebrahimi		return NULL;
2242*9a0e4156SSadaf Ebrahimi	}
2243*9a0e4156SSadaf Ebrahimi
2244*9a0e4156SSadaf Ebrahimi	return handle->reg_name(ud, reg);
2245*9a0e4156SSadaf Ebrahimi}
2246*9a0e4156SSadaf Ebrahimi```
2247*9a0e4156SSadaf Ebrahimi
2248*9a0e4156SSadaf Ebrahimi</details>
2249*9a0e4156SSadaf Ebrahimi
2250*9a0e4156SSadaf Ebrahimi
2251*9a0e4156SSadaf Ebrahimi<details><summary> 示例(打印RAX) </summary>
2252*9a0e4156SSadaf Ebrahimi
2253*9a0e4156SSadaf Ebrahimi```cpp
2254*9a0e4156SSadaf Ebrahimi#include <iostream>
2255*9a0e4156SSadaf Ebrahimi#include <stdio.h>
2256*9a0e4156SSadaf Ebrahimi
2257*9a0e4156SSadaf Ebrahimi#include "capstone.h"
2258*9a0e4156SSadaf Ebrahimi#include "platform.h"
2259*9a0e4156SSadaf Ebrahimi
2260*9a0e4156SSadaf Ebrahimiusing namespace std;
2261*9a0e4156SSadaf Ebrahimi
2262*9a0e4156SSadaf Ebrahimiint main(void)
2263*9a0e4156SSadaf Ebrahimi{
2264*9a0e4156SSadaf Ebrahimi	csh handle = 0;
2265*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
2266*9a0e4156SSadaf Ebrahimi	size_t count;
2267*9a0e4156SSadaf Ebrahimi
2268*9a0e4156SSadaf Ebrahimi	if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle)) {
2269*9a0e4156SSadaf Ebrahimi		printf("ERROR: Failed to initialize engine!\n");
2270*9a0e4156SSadaf Ebrahimi		return -1;
2271*9a0e4156SSadaf Ebrahimi	}
2272*9a0e4156SSadaf Ebrahimi
2273*9a0e4156SSadaf Ebrahimi	printf("%s", cs_reg_name(handle, X86_REG_RAX));
2274*9a0e4156SSadaf Ebrahimi	cs_close(&handle);
2275*9a0e4156SSadaf Ebrahimi
2276*9a0e4156SSadaf Ebrahimi	return 0;
2277*9a0e4156SSadaf Ebrahimi}
2278*9a0e4156SSadaf Ebrahimi```
2279*9a0e4156SSadaf Ebrahimi
2280*9a0e4156SSadaf Ebrahimi</details>
2281*9a0e4156SSadaf Ebrahimi
2282*9a0e4156SSadaf Ebrahimi输出
2283*9a0e4156SSadaf Ebrahimi
2284*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/21.jpg)
2285*9a0e4156SSadaf Ebrahimi
2286*9a0e4156SSadaf Ebrahimi
2287*9a0e4156SSadaf Ebrahimi### cs_insn_name
2288*9a0e4156SSadaf Ebrahimi
2289*9a0e4156SSadaf Ebrahimi`const char * CAPSTONE_API cs_insn_name(csh handle, unsigned int insn_id);`
2290*9a0e4156SSadaf Ebrahimi
2291*9a0e4156SSadaf Ebrahimi获取指令的名字(string类型)
2292*9a0e4156SSadaf Ebrahimi
2293*9a0e4156SSadaf Ebrahimi指令id可在相关架构的头文件(建立项目时复制到项目文件夹的那些头文件)内找到
2294*9a0e4156SSadaf Ebrahimi
2295*9a0e4156SSadaf Ebrahimi注意: 当处于diet模式时此API不可用,因为引擎不会存储寄存器名
2296*9a0e4156SSadaf Ebrahimi
2297*9a0e4156SSadaf Ebrahimi```
2298*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
2299*9a0e4156SSadaf Ebrahimiinsn_id: 指令id
2300*9a0e4156SSadaf Ebrahimireturn: 指令的字符名, 如果insn_id不可用返回NULL
2301*9a0e4156SSadaf Ebrahimi```
2302*9a0e4156SSadaf Ebrahimi
2303*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
2304*9a0e4156SSadaf Ebrahimi
2305*9a0e4156SSadaf Ebrahimi```cpp
2306*9a0e4156SSadaf Ebrahimiconst char * CAPSTONE_API cs_insn_name(csh ud, unsigned int insn)
2307*9a0e4156SSadaf Ebrahimi{
2308*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
2309*9a0e4156SSadaf Ebrahimi
2310*9a0e4156SSadaf Ebrahimi	if (!handle || handle->insn_name == NULL) {
2311*9a0e4156SSadaf Ebrahimi		return NULL;
2312*9a0e4156SSadaf Ebrahimi	}
2313*9a0e4156SSadaf Ebrahimi
2314*9a0e4156SSadaf Ebrahimi	return handle->insn_name(ud, insn);
2315*9a0e4156SSadaf Ebrahimi}
2316*9a0e4156SSadaf Ebrahimi```
2317*9a0e4156SSadaf Ebrahimi
2318*9a0e4156SSadaf Ebrahimi</details>
2319*9a0e4156SSadaf Ebrahimi
2320*9a0e4156SSadaf Ebrahimi
2321*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary>
2322*9a0e4156SSadaf Ebrahimi
2323*9a0e4156SSadaf Ebrahimi```cpp
2324*9a0e4156SSadaf Ebrahimi#include <iostream>
2325*9a0e4156SSadaf Ebrahimi#include <stdio.h>
2326*9a0e4156SSadaf Ebrahimi
2327*9a0e4156SSadaf Ebrahimi#include "capstone.h"
2328*9a0e4156SSadaf Ebrahimi#include "platform.h"
2329*9a0e4156SSadaf Ebrahimi
2330*9a0e4156SSadaf Ebrahimiusing namespace std;
2331*9a0e4156SSadaf Ebrahimi
2332*9a0e4156SSadaf Ebrahimistruct platform {
2333*9a0e4156SSadaf Ebrahimi	cs_arch arch;
2334*9a0e4156SSadaf Ebrahimi	cs_mode mode;
2335*9a0e4156SSadaf Ebrahimi	unsigned char* code;
2336*9a0e4156SSadaf Ebrahimi	size_t size;
2337*9a0e4156SSadaf Ebrahimi	const char* comment;
2338*9a0e4156SSadaf Ebrahimi	cs_opt_type opt_type;
2339*9a0e4156SSadaf Ebrahimi	cs_opt_value opt_value;
2340*9a0e4156SSadaf Ebrahimi};
2341*9a0e4156SSadaf Ebrahimi
2342*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len)
2343*9a0e4156SSadaf Ebrahimi{
2344*9a0e4156SSadaf Ebrahimi	unsigned char* c;
2345*9a0e4156SSadaf Ebrahimi
2346*9a0e4156SSadaf Ebrahimi	printf("Code: ");
2347*9a0e4156SSadaf Ebrahimi	for (c = str; c < str + len; c++) {
2348*9a0e4156SSadaf Ebrahimi		printf("0x%02x ", *c & 0xff);
2349*9a0e4156SSadaf Ebrahimi	}
2350*9a0e4156SSadaf Ebrahimi	printf("\n");
2351*9a0e4156SSadaf Ebrahimi}
2352*9a0e4156SSadaf Ebrahimi
2353*9a0e4156SSadaf Ebrahimistatic void test()
2354*9a0e4156SSadaf Ebrahimi{
2355*9a0e4156SSadaf Ebrahimi
2356*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
2357*9a0e4156SSadaf Ebrahimi
2358*9a0e4156SSadaf Ebrahimi	struct platform platforms[] = {
2359*9a0e4156SSadaf Ebrahimi		{
2360*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
2361*9a0e4156SSadaf Ebrahimi			CS_MODE_64,
2362*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE64,
2363*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE64) - 1,
2364*9a0e4156SSadaf Ebrahimi			"X86 64 (Intel syntax)"
2365*9a0e4156SSadaf Ebrahimi		},
2366*9a0e4156SSadaf Ebrahimi	};
2367*9a0e4156SSadaf Ebrahimi
2368*9a0e4156SSadaf Ebrahimi	csh handle;
2369*9a0e4156SSadaf Ebrahimi	uint64_t address;
2370*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
2371*9a0e4156SSadaf Ebrahimi	cs_detail* detail;
2372*9a0e4156SSadaf Ebrahimi	int i;
2373*9a0e4156SSadaf Ebrahimi	cs_err err;
2374*9a0e4156SSadaf Ebrahimi	const uint8_t* code;
2375*9a0e4156SSadaf Ebrahimi	size_t size;
2376*9a0e4156SSadaf Ebrahimi
2377*9a0e4156SSadaf Ebrahimi	for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
2378*9a0e4156SSadaf Ebrahimi		printf("****************\n");
2379*9a0e4156SSadaf Ebrahimi		printf("Platform: %s\n", platforms[i].comment);
2380*9a0e4156SSadaf Ebrahimi		err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
2381*9a0e4156SSadaf Ebrahimi		if (err) {
2382*9a0e4156SSadaf Ebrahimi			printf("Failed on cs_open() with error returned: %u\n", err);
2383*9a0e4156SSadaf Ebrahimi			abort();
2384*9a0e4156SSadaf Ebrahimi		}
2385*9a0e4156SSadaf Ebrahimi
2386*9a0e4156SSadaf Ebrahimi		if (platforms[i].opt_type)
2387*9a0e4156SSadaf Ebrahimi			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
2388*9a0e4156SSadaf Ebrahimi
2389*9a0e4156SSadaf Ebrahimi		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
2390*9a0e4156SSadaf Ebrahimi
2391*9a0e4156SSadaf Ebrahimi		insn = cs_malloc(handle);
2392*9a0e4156SSadaf Ebrahimi
2393*9a0e4156SSadaf Ebrahimi		print_string_hex(platforms[i].code, platforms[i].size);
2394*9a0e4156SSadaf Ebrahimi		printf("Disasm:\n");
2395*9a0e4156SSadaf Ebrahimi
2396*9a0e4156SSadaf Ebrahimi		address = 0x1000;
2397*9a0e4156SSadaf Ebrahimi		code = platforms[i].code;
2398*9a0e4156SSadaf Ebrahimi		size = platforms[i].size;
2399*9a0e4156SSadaf Ebrahimi		while (cs_disasm_iter(handle, &code, &size, &address, insn)) {
2400*9a0e4156SSadaf Ebrahimi			int n;
2401*9a0e4156SSadaf Ebrahimi
2402*9a0e4156SSadaf Ebrahimi			printf("0x%" PRIx64 ":\t%s\t\t%s",
2403*9a0e4156SSadaf Ebrahimi				insn->address, insn->mnemonic, insn->op_str);
2404*9a0e4156SSadaf Ebrahimi			printf("            instruction:  %s", cs_insn_name(handle, insn->id));   //输出该行的操作指令
2405*9a0e4156SSadaf Ebrahimi			cout << endl;
2406*9a0e4156SSadaf Ebrahimi
2407*9a0e4156SSadaf Ebrahimi		printf("\n");
2408*9a0e4156SSadaf Ebrahimi		cs_free(insn, 1);
2409*9a0e4156SSadaf Ebrahimi		cs_close(&handle);
2410*9a0e4156SSadaf Ebrahimi	}
2411*9a0e4156SSadaf Ebrahimi}
2412*9a0e4156SSadaf Ebrahimi
2413*9a0e4156SSadaf Ebrahimiint main()
2414*9a0e4156SSadaf Ebrahimi{
2415*9a0e4156SSadaf Ebrahimi	test();
2416*9a0e4156SSadaf Ebrahimi
2417*9a0e4156SSadaf Ebrahimi	return 0;
2418*9a0e4156SSadaf Ebrahimi}
2419*9a0e4156SSadaf Ebrahimi```
2420*9a0e4156SSadaf Ebrahimi
2421*9a0e4156SSadaf Ebrahimi</details>
2422*9a0e4156SSadaf Ebrahimi
2423*9a0e4156SSadaf Ebrahimi输出
2424*9a0e4156SSadaf Ebrahimi
2425*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/22.jpg)
2426*9a0e4156SSadaf Ebrahimi
2427*9a0e4156SSadaf Ebrahimi
2428*9a0e4156SSadaf Ebrahimi### cs_group_name
2429*9a0e4156SSadaf Ebrahimi
2430*9a0e4156SSadaf Ebrahimi`const char * CAPSTONE_API cs_group_name(csh handle, unsigned int group_id);`
2431*9a0e4156SSadaf Ebrahimi
2432*9a0e4156SSadaf Ebrahimi输出指令类型名字
2433*9a0e4156SSadaf Ebrahimi
2434*9a0e4156SSadaf Ebrahimi指令id可在相关架构的头文件(建立项目时复制到项目文件夹的那些头文件)内找到
2435*9a0e4156SSadaf Ebrahimi
2436*9a0e4156SSadaf Ebrahimi注意: 当处于diet模式时此API不可用,因为引擎不会存储寄存器名
2437*9a0e4156SSadaf Ebrahimi
2438*9a0e4156SSadaf Ebrahimi```
2439*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
2440*9a0e4156SSadaf Ebrahimiinsn_id: 指令类型id
2441*9a0e4156SSadaf Ebrahimireturn: 指令类型的字符名, 如果insn_id不可用返回NULL
2442*9a0e4156SSadaf Ebrahimi```
2443*9a0e4156SSadaf Ebrahimi
2444*9a0e4156SSadaf Ebrahimi示例都与上面类似,略。
2445*9a0e4156SSadaf Ebrahimi
2446*9a0e4156SSadaf Ebrahimi
2447*9a0e4156SSadaf Ebrahimi### cs_insn_group
2448*9a0e4156SSadaf Ebrahimi
2449*9a0e4156SSadaf Ebrahimi`bool CAPSTONE_API cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id);`
2450*9a0e4156SSadaf Ebrahimi
2451*9a0e4156SSadaf Ebrahimi检查反汇编后的指令是否属于某个特定指令类型
2452*9a0e4156SSadaf Ebrahimi
2453*9a0e4156SSadaf Ebrahimi注意:只有当detail选项为ON时这个API可用 (默认OFF).
2454*9a0e4156SSadaf Ebrahimi
2455*9a0e4156SSadaf Ebrahimi在“diet”模式下,此API没有用,因为引擎不更新insn->groups数组
2456*9a0e4156SSadaf Ebrahimi
2457*9a0e4156SSadaf Ebrahimi```
2458*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
2459*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构
2460*9a0e4156SSadaf Ebrahimigroup_id: 要检查此指令是否属于的指令类型。
2461*9a0e4156SSadaf Ebrahimireturn: 如果该指令确实属于给定的指令类型,则为true,否则为false。
2462*9a0e4156SSadaf Ebrahimi```
2463*9a0e4156SSadaf Ebrahimi
2464*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
2465*9a0e4156SSadaf Ebrahimi
2466*9a0e4156SSadaf Ebrahimi```cpp
2467*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id)
2468*9a0e4156SSadaf Ebrahimi{
2469*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
2470*9a0e4156SSadaf Ebrahimi	if (!ud)
2471*9a0e4156SSadaf Ebrahimi		return false;
2472*9a0e4156SSadaf Ebrahimi
2473*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
2474*9a0e4156SSadaf Ebrahimi
2475*9a0e4156SSadaf Ebrahimi	if (!handle->detail) {
2476*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2477*9a0e4156SSadaf Ebrahimi		return false;
2478*9a0e4156SSadaf Ebrahimi	}
2479*9a0e4156SSadaf Ebrahimi
2480*9a0e4156SSadaf Ebrahimi	if (!insn->id) {
2481*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_SKIPDATA;
2482*9a0e4156SSadaf Ebrahimi		return false;
2483*9a0e4156SSadaf Ebrahimi	}
2484*9a0e4156SSadaf Ebrahimi
2485*9a0e4156SSadaf Ebrahimi	if (!insn->detail) {
2486*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2487*9a0e4156SSadaf Ebrahimi		return false;
2488*9a0e4156SSadaf Ebrahimi	}
2489*9a0e4156SSadaf Ebrahimi
2490*9a0e4156SSadaf Ebrahimi	return arr_exist8(insn->detail->groups, insn->detail->groups_count, group_id);
2491*9a0e4156SSadaf Ebrahimi}
2492*9a0e4156SSadaf Ebrahimi```
2493*9a0e4156SSadaf Ebrahimi
2494*9a0e4156SSadaf Ebrahimi</details>
2495*9a0e4156SSadaf Ebrahimi
2496*9a0e4156SSadaf Ebrahimi
2497*9a0e4156SSadaf Ebrahimi<details><summary> 示例(判断是否属于跳转指令) </summary>
2498*9a0e4156SSadaf Ebrahimi
2499*9a0e4156SSadaf Ebrahimi```cpp
2500*9a0e4156SSadaf Ebrahimi#include <iostream>
2501*9a0e4156SSadaf Ebrahimi#include <stdio.h>
2502*9a0e4156SSadaf Ebrahimi
2503*9a0e4156SSadaf Ebrahimi#include "capstone.h"
2504*9a0e4156SSadaf Ebrahimi#include "platform.h"
2505*9a0e4156SSadaf Ebrahimi
2506*9a0e4156SSadaf Ebrahimiusing namespace std;
2507*9a0e4156SSadaf Ebrahimi
2508*9a0e4156SSadaf Ebrahimistruct platform {
2509*9a0e4156SSadaf Ebrahimi	cs_arch arch;
2510*9a0e4156SSadaf Ebrahimi	cs_mode mode;
2511*9a0e4156SSadaf Ebrahimi	unsigned char* code;
2512*9a0e4156SSadaf Ebrahimi	size_t size;
2513*9a0e4156SSadaf Ebrahimi	const char* comment;
2514*9a0e4156SSadaf Ebrahimi	cs_opt_type opt_type;
2515*9a0e4156SSadaf Ebrahimi	cs_opt_value opt_value;
2516*9a0e4156SSadaf Ebrahimi};
2517*9a0e4156SSadaf Ebrahimi
2518*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len)
2519*9a0e4156SSadaf Ebrahimi{
2520*9a0e4156SSadaf Ebrahimi	unsigned char* c;
2521*9a0e4156SSadaf Ebrahimi
2522*9a0e4156SSadaf Ebrahimi	printf("Code: ");
2523*9a0e4156SSadaf Ebrahimi	for (c = str; c < str + len; c++) {
2524*9a0e4156SSadaf Ebrahimi		printf("0x%02x ", *c & 0xff);
2525*9a0e4156SSadaf Ebrahimi	}
2526*9a0e4156SSadaf Ebrahimi	printf("\n");
2527*9a0e4156SSadaf Ebrahimi}
2528*9a0e4156SSadaf Ebrahimi
2529*9a0e4156SSadaf Ebrahimistatic void test()
2530*9a0e4156SSadaf Ebrahimi{
2531*9a0e4156SSadaf Ebrahimi
2532*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
2533*9a0e4156SSadaf Ebrahimi
2534*9a0e4156SSadaf Ebrahimi	struct platform platforms[] = {
2535*9a0e4156SSadaf Ebrahimi		{
2536*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
2537*9a0e4156SSadaf Ebrahimi			CS_MODE_64,
2538*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE64,
2539*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE64) - 1,
2540*9a0e4156SSadaf Ebrahimi			"X86 64 (Intel syntax)"
2541*9a0e4156SSadaf Ebrahimi		},
2542*9a0e4156SSadaf Ebrahimi	};
2543*9a0e4156SSadaf Ebrahimi
2544*9a0e4156SSadaf Ebrahimi	csh handle;
2545*9a0e4156SSadaf Ebrahimi	uint64_t address;
2546*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
2547*9a0e4156SSadaf Ebrahimi	cs_detail* detail;
2548*9a0e4156SSadaf Ebrahimi	int i;
2549*9a0e4156SSadaf Ebrahimi	cs_err err;
2550*9a0e4156SSadaf Ebrahimi	const uint8_t* code;
2551*9a0e4156SSadaf Ebrahimi	size_t size;
2552*9a0e4156SSadaf Ebrahimi
2553*9a0e4156SSadaf Ebrahimi	for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
2554*9a0e4156SSadaf Ebrahimi		printf("****************\n");
2555*9a0e4156SSadaf Ebrahimi		printf("Platform: %s\n", platforms[i].comment);
2556*9a0e4156SSadaf Ebrahimi		err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
2557*9a0e4156SSadaf Ebrahimi		if (err) {
2558*9a0e4156SSadaf Ebrahimi			printf("Failed on cs_open() with error returned: %u\n", err);
2559*9a0e4156SSadaf Ebrahimi			abort();
2560*9a0e4156SSadaf Ebrahimi		}
2561*9a0e4156SSadaf Ebrahimi
2562*9a0e4156SSadaf Ebrahimi		if (platforms[i].opt_type)
2563*9a0e4156SSadaf Ebrahimi			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
2564*9a0e4156SSadaf Ebrahimi
2565*9a0e4156SSadaf Ebrahimi		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
2566*9a0e4156SSadaf Ebrahimi
2567*9a0e4156SSadaf Ebrahimi		insn = cs_malloc(handle);
2568*9a0e4156SSadaf Ebrahimi
2569*9a0e4156SSadaf Ebrahimi		print_string_hex(platforms[i].code, platforms[i].size);
2570*9a0e4156SSadaf Ebrahimi		printf("Disasm:\n");
2571*9a0e4156SSadaf Ebrahimi
2572*9a0e4156SSadaf Ebrahimi		address = 0x1000;
2573*9a0e4156SSadaf Ebrahimi		code = platforms[i].code;
2574*9a0e4156SSadaf Ebrahimi		size = platforms[i].size;
2575*9a0e4156SSadaf Ebrahimi		while (cs_disasm_iter(handle, &code, &size, &address, insn)) {
2576*9a0e4156SSadaf Ebrahimi			int n;
2577*9a0e4156SSadaf Ebrahimi
2578*9a0e4156SSadaf Ebrahimi			printf("0x%" PRIx64 ":\t%s\t\t%s          ",
2579*9a0e4156SSadaf Ebrahimi				insn->address, insn->mnemonic, insn->op_str);
2580*9a0e4156SSadaf Ebrahimi			cout << "is JUMP:   " <<cs_insn_group(handle, insn, CS_GRP_JUMP) << endl;   //判断是否为跳转指令
2581*9a0e4156SSadaf Ebrahimi			cout << endl;
2582*9a0e4156SSadaf Ebrahimi
2583*9a0e4156SSadaf Ebrahimi		printf("\n");
2584*9a0e4156SSadaf Ebrahimi		cs_free(insn, 1);
2585*9a0e4156SSadaf Ebrahimi		cs_close(&handle);
2586*9a0e4156SSadaf Ebrahimi	}
2587*9a0e4156SSadaf Ebrahimi}
2588*9a0e4156SSadaf Ebrahimi
2589*9a0e4156SSadaf Ebrahimiint main()
2590*9a0e4156SSadaf Ebrahimi{
2591*9a0e4156SSadaf Ebrahimi	test();
2592*9a0e4156SSadaf Ebrahimi
2593*9a0e4156SSadaf Ebrahimi	return 0;
2594*9a0e4156SSadaf Ebrahimi}
2595*9a0e4156SSadaf Ebrahimi```
2596*9a0e4156SSadaf Ebrahimi
2597*9a0e4156SSadaf Ebrahimi</details>
2598*9a0e4156SSadaf Ebrahimi
2599*9a0e4156SSadaf Ebrahimi输出
2600*9a0e4156SSadaf Ebrahimi
2601*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/23.jpg)
2602*9a0e4156SSadaf Ebrahimi
2603*9a0e4156SSadaf Ebrahimi
2604*9a0e4156SSadaf Ebrahimi### cs_reg_read
2605*9a0e4156SSadaf Ebrahimi
2606*9a0e4156SSadaf Ebrahimi`bool CAPSTONE_API cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id);`
2607*9a0e4156SSadaf Ebrahimi
2608*9a0e4156SSadaf Ebrahimi检查反汇编指令是否隐式使用特定寄存器。
2609*9a0e4156SSadaf Ebrahimi
2610*9a0e4156SSadaf Ebrahimi注意:此API仅在启用detail选项时有效(默认为关闭)
2611*9a0e4156SSadaf Ebrahimi
2612*9a0e4156SSadaf Ebrahimi在“diet”模式下,此API没有用,因为引擎不更新insn->regs_read数组
2613*9a0e4156SSadaf Ebrahimi
2614*9a0e4156SSadaf Ebrahimi```
2615*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构
2616*9a0e4156SSadaf Ebrahimireg_id: 标注想要检查的这个指令是否使用了它。
2617*9a0e4156SSadaf Ebrahimireturn: 如果该指令确实隐式使用了给定寄存器,则为true,否则为false。
2618*9a0e4156SSadaf Ebrahimi```
2619*9a0e4156SSadaf Ebrahimi
2620*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
2621*9a0e4156SSadaf Ebrahimi
2622*9a0e4156SSadaf Ebrahimi```cpp
2623*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id)
2624*9a0e4156SSadaf Ebrahimi{
2625*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
2626*9a0e4156SSadaf Ebrahimi	if (!ud)
2627*9a0e4156SSadaf Ebrahimi		return false;
2628*9a0e4156SSadaf Ebrahimi
2629*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
2630*9a0e4156SSadaf Ebrahimi
2631*9a0e4156SSadaf Ebrahimi	if (!handle->detail) {
2632*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2633*9a0e4156SSadaf Ebrahimi		return false;
2634*9a0e4156SSadaf Ebrahimi	}
2635*9a0e4156SSadaf Ebrahimi
2636*9a0e4156SSadaf Ebrahimi	if (!insn->id) {
2637*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_SKIPDATA;
2638*9a0e4156SSadaf Ebrahimi		return false;
2639*9a0e4156SSadaf Ebrahimi	}
2640*9a0e4156SSadaf Ebrahimi
2641*9a0e4156SSadaf Ebrahimi	if (!insn->detail) {
2642*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2643*9a0e4156SSadaf Ebrahimi		return false;
2644*9a0e4156SSadaf Ebrahimi	}
2645*9a0e4156SSadaf Ebrahimi
2646*9a0e4156SSadaf Ebrahimi	return arr_exist(insn->detail->regs_read, insn->detail->regs_read_count, reg_id);
2647*9a0e4156SSadaf Ebrahimi}
2648*9a0e4156SSadaf Ebrahimi```
2649*9a0e4156SSadaf Ebrahimi</details>
2650*9a0e4156SSadaf Ebrahimi
2651*9a0e4156SSadaf Ebrahimi示例同API cs_disasm_iter
2652*9a0e4156SSadaf Ebrahimi
2653*9a0e4156SSadaf Ebrahimi
2654*9a0e4156SSadaf Ebrahimi### cs_reg_write
2655*9a0e4156SSadaf Ebrahimi
2656*9a0e4156SSadaf Ebrahimi`bool CAPSTONE_API cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id);`
2657*9a0e4156SSadaf Ebrahimi
2658*9a0e4156SSadaf Ebrahimi检查反汇编指令是否隐式修改了特定寄存器。
2659*9a0e4156SSadaf Ebrahimi
2660*9a0e4156SSadaf Ebrahimi注意:此API仅在启用detail选项时有效(默认为关闭)
2661*9a0e4156SSadaf Ebrahimi
2662*9a0e4156SSadaf Ebrahimi在“diet”模式下,此API没有用,因为引擎不更新insn->regs_read数组
2663*9a0e4156SSadaf Ebrahimi
2664*9a0e4156SSadaf Ebrahimi```
2665*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构
2666*9a0e4156SSadaf Ebrahimireg_id: 标注想要检查的这个指令是否修改了它。
2667*9a0e4156SSadaf Ebrahimireturn: 如果该指令确实隐式修改了给定寄存器,则为true,否则为false。
2668*9a0e4156SSadaf Ebrahimi```
2669*9a0e4156SSadaf Ebrahimi
2670*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
2671*9a0e4156SSadaf Ebrahimi
2672*9a0e4156SSadaf Ebrahimi```cpp
2673*9a0e4156SSadaf Ebrahimibool CAPSTONE_API cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id)
2674*9a0e4156SSadaf Ebrahimi{
2675*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
2676*9a0e4156SSadaf Ebrahimi	if (!ud)
2677*9a0e4156SSadaf Ebrahimi		return false;
2678*9a0e4156SSadaf Ebrahimi
2679*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
2680*9a0e4156SSadaf Ebrahimi
2681*9a0e4156SSadaf Ebrahimi	if (!handle->detail) {
2682*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2683*9a0e4156SSadaf Ebrahimi		return false;
2684*9a0e4156SSadaf Ebrahimi	}
2685*9a0e4156SSadaf Ebrahimi
2686*9a0e4156SSadaf Ebrahimi	if (!insn->id) {
2687*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_SKIPDATA;
2688*9a0e4156SSadaf Ebrahimi		return false;
2689*9a0e4156SSadaf Ebrahimi	}
2690*9a0e4156SSadaf Ebrahimi
2691*9a0e4156SSadaf Ebrahimi	if (!insn->detail) {
2692*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2693*9a0e4156SSadaf Ebrahimi		return false;
2694*9a0e4156SSadaf Ebrahimi	}
2695*9a0e4156SSadaf Ebrahimi
2696*9a0e4156SSadaf Ebrahimi	return arr_exist(insn->detail->regs_write, insn->detail->regs_write_count, reg_id);
2697*9a0e4156SSadaf Ebrahimi}
2698*9a0e4156SSadaf Ebrahimi```
2699*9a0e4156SSadaf Ebrahimi</details>
2700*9a0e4156SSadaf Ebrahimi
2701*9a0e4156SSadaf Ebrahimi示例同API cs_disasm_iter
2702*9a0e4156SSadaf Ebrahimi
2703*9a0e4156SSadaf Ebrahimi
2704*9a0e4156SSadaf Ebrahimi### cs_op_count
2705*9a0e4156SSadaf Ebrahimi
2706*9a0e4156SSadaf Ebrahimi`int CAPSTONE_API cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type);`
2707*9a0e4156SSadaf Ebrahimi
2708*9a0e4156SSadaf Ebrahimi计算给定类型的操作数的数量
2709*9a0e4156SSadaf Ebrahimi
2710*9a0e4156SSadaf Ebrahimi注意:只有当detail选项为ON时这个API可用 (默认OFF).
2711*9a0e4156SSadaf Ebrahimi
2712*9a0e4156SSadaf Ebrahimi```
2713*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
2714*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构
2715*9a0e4156SSadaf Ebrahimiop_type: 要找到的操作数类型。
2716*9a0e4156SSadaf Ebrahimireturn: 指令insn中给定类型op_type的操作数的数量,返回-1表示查找失败。
2717*9a0e4156SSadaf Ebrahimi```
2718*9a0e4156SSadaf Ebrahimi
2719*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
2720*9a0e4156SSadaf Ebrahimi
2721*9a0e4156SSadaf Ebrahimi```cpp
2722*9a0e4156SSadaf Ebrahimiint CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type)
2723*9a0e4156SSadaf Ebrahimi{
2724*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
2725*9a0e4156SSadaf Ebrahimi	unsigned int count = 0, i;
2726*9a0e4156SSadaf Ebrahimi	if (!ud)
2727*9a0e4156SSadaf Ebrahimi		return -1;
2728*9a0e4156SSadaf Ebrahimi
2729*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
2730*9a0e4156SSadaf Ebrahimi
2731*9a0e4156SSadaf Ebrahimi	if (!handle->detail) {
2732*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2733*9a0e4156SSadaf Ebrahimi		return -1;
2734*9a0e4156SSadaf Ebrahimi	}
2735*9a0e4156SSadaf Ebrahimi
2736*9a0e4156SSadaf Ebrahimi	if (!insn->id) {
2737*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_SKIPDATA;
2738*9a0e4156SSadaf Ebrahimi		return -1;
2739*9a0e4156SSadaf Ebrahimi	}
2740*9a0e4156SSadaf Ebrahimi
2741*9a0e4156SSadaf Ebrahimi	if (!insn->detail) {
2742*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2743*9a0e4156SSadaf Ebrahimi		return -1;
2744*9a0e4156SSadaf Ebrahimi	}
2745*9a0e4156SSadaf Ebrahimi
2746*9a0e4156SSadaf Ebrahimi	handle->errnum = CS_ERR_OK;
2747*9a0e4156SSadaf Ebrahimi
2748*9a0e4156SSadaf Ebrahimi	switch (handle->arch) {
2749*9a0e4156SSadaf Ebrahimi		default:
2750*9a0e4156SSadaf Ebrahimi			handle->errnum = CS_ERR_HANDLE;
2751*9a0e4156SSadaf Ebrahimi			return -1;
2752*9a0e4156SSadaf Ebrahimi		case CS_ARCH_ARM:
2753*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->arm.op_count; i++)
2754*9a0e4156SSadaf Ebrahimi				if (insn->detail->arm.operands[i].type == (arm_op_type)op_type)
2755*9a0e4156SSadaf Ebrahimi					count++;
2756*9a0e4156SSadaf Ebrahimi			break;
2757*9a0e4156SSadaf Ebrahimi		case CS_ARCH_ARM64:
2758*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->arm64.op_count; i++)
2759*9a0e4156SSadaf Ebrahimi				if (insn->detail->arm64.operands[i].type == (arm64_op_type)op_type)
2760*9a0e4156SSadaf Ebrahimi					count++;
2761*9a0e4156SSadaf Ebrahimi			break;
2762*9a0e4156SSadaf Ebrahimi		case CS_ARCH_X86:
2763*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->x86.op_count; i++)
2764*9a0e4156SSadaf Ebrahimi				if (insn->detail->x86.operands[i].type == (x86_op_type)op_type)
2765*9a0e4156SSadaf Ebrahimi					count++;
2766*9a0e4156SSadaf Ebrahimi			break;
2767*9a0e4156SSadaf Ebrahimi		case CS_ARCH_MIPS:
2768*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->mips.op_count; i++)
2769*9a0e4156SSadaf Ebrahimi				if (insn->detail->mips.operands[i].type == (mips_op_type)op_type)
2770*9a0e4156SSadaf Ebrahimi					count++;
2771*9a0e4156SSadaf Ebrahimi			break;
2772*9a0e4156SSadaf Ebrahimi		case CS_ARCH_PPC:
2773*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->ppc.op_count; i++)
2774*9a0e4156SSadaf Ebrahimi				if (insn->detail->ppc.operands[i].type == (ppc_op_type)op_type)
2775*9a0e4156SSadaf Ebrahimi					count++;
2776*9a0e4156SSadaf Ebrahimi			break;
2777*9a0e4156SSadaf Ebrahimi		case CS_ARCH_SPARC:
2778*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->sparc.op_count; i++)
2779*9a0e4156SSadaf Ebrahimi				if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type)
2780*9a0e4156SSadaf Ebrahimi					count++;
2781*9a0e4156SSadaf Ebrahimi			break;
2782*9a0e4156SSadaf Ebrahimi		case CS_ARCH_SYSZ:
2783*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->sysz.op_count; i++)
2784*9a0e4156SSadaf Ebrahimi				if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type)
2785*9a0e4156SSadaf Ebrahimi					count++;
2786*9a0e4156SSadaf Ebrahimi			break;
2787*9a0e4156SSadaf Ebrahimi		case CS_ARCH_XCORE:
2788*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->xcore.op_count; i++)
2789*9a0e4156SSadaf Ebrahimi				if (insn->detail->xcore.operands[i].type == (xcore_op_type)op_type)
2790*9a0e4156SSadaf Ebrahimi					count++;
2791*9a0e4156SSadaf Ebrahimi			break;
2792*9a0e4156SSadaf Ebrahimi		case CS_ARCH_M68K:
2793*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->m68k.op_count; i++)
2794*9a0e4156SSadaf Ebrahimi				if (insn->detail->m68k.operands[i].type == (m68k_op_type)op_type)
2795*9a0e4156SSadaf Ebrahimi					count++;
2796*9a0e4156SSadaf Ebrahimi			break;
2797*9a0e4156SSadaf Ebrahimi		case CS_ARCH_TMS320C64X:
2798*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->tms320c64x.op_count; i++)
2799*9a0e4156SSadaf Ebrahimi				if (insn->detail->tms320c64x.operands[i].type == (tms320c64x_op_type)op_type)
2800*9a0e4156SSadaf Ebrahimi					count++;
2801*9a0e4156SSadaf Ebrahimi			break;
2802*9a0e4156SSadaf Ebrahimi		case CS_ARCH_M680X:
2803*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->m680x.op_count; i++)
2804*9a0e4156SSadaf Ebrahimi				if (insn->detail->m680x.operands[i].type == (m680x_op_type)op_type)
2805*9a0e4156SSadaf Ebrahimi					count++;
2806*9a0e4156SSadaf Ebrahimi			break;
2807*9a0e4156SSadaf Ebrahimi		case CS_ARCH_EVM:
2808*9a0e4156SSadaf Ebrahimi#if 0
2809*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->evm.op_count; i++)
2810*9a0e4156SSadaf Ebrahimi				if (insn->detail->evm.operands[i].type == (evm_op_type)op_type)
2811*9a0e4156SSadaf Ebrahimi					count++;
2812*9a0e4156SSadaf Ebrahimi#endif
2813*9a0e4156SSadaf Ebrahimi			break;
2814*9a0e4156SSadaf Ebrahimi	}
2815*9a0e4156SSadaf Ebrahimi
2816*9a0e4156SSadaf Ebrahimi	return count;
2817*9a0e4156SSadaf Ebrahimi}
2818*9a0e4156SSadaf Ebrahimi```
2819*9a0e4156SSadaf Ebrahimi
2820*9a0e4156SSadaf Ebrahimi</details>
2821*9a0e4156SSadaf Ebrahimi
2822*9a0e4156SSadaf Ebrahimi
2823*9a0e4156SSadaf Ebrahimi<details><summary> x86指令操作码类型示例(判断寄存操作码) </summary>
2824*9a0e4156SSadaf Ebrahimi
2825*9a0e4156SSadaf Ebrahimi```cpp
2826*9a0e4156SSadaf Ebrahimitypedef enum x86_op_type {
2827*9a0e4156SSadaf Ebrahimi	X86_OP_INVALID = 0, ///< = CS_OP_INVALID (未初始化).
2828*9a0e4156SSadaf Ebrahimi	X86_OP_REG, ///< = CS_OP_REG (寄存操作码).
2829*9a0e4156SSadaf Ebrahimi	X86_OP_IMM, ///< = CS_OP_IMM (立即操作码).
2830*9a0e4156SSadaf Ebrahimi	X86_OP_MEM, ///< = CS_OP_MEM (内存操作码).
2831*9a0e4156SSadaf Ebrahimi} x86_op_type;
2832*9a0e4156SSadaf Ebrahimi```
2833*9a0e4156SSadaf Ebrahimi
2834*9a0e4156SSadaf Ebrahimi```cpp
2835*9a0e4156SSadaf Ebrahimi#include <iostream>
2836*9a0e4156SSadaf Ebrahimi#include <stdio.h>
2837*9a0e4156SSadaf Ebrahimi
2838*9a0e4156SSadaf Ebrahimi#include "capstone.h"
2839*9a0e4156SSadaf Ebrahimi#include "platform.h"
2840*9a0e4156SSadaf Ebrahimi
2841*9a0e4156SSadaf Ebrahimiusing namespace std;
2842*9a0e4156SSadaf Ebrahimi
2843*9a0e4156SSadaf Ebrahimistruct platform {
2844*9a0e4156SSadaf Ebrahimi	cs_arch arch;
2845*9a0e4156SSadaf Ebrahimi	cs_mode mode;
2846*9a0e4156SSadaf Ebrahimi	unsigned char* code;
2847*9a0e4156SSadaf Ebrahimi	size_t size;
2848*9a0e4156SSadaf Ebrahimi	const char* comment;
2849*9a0e4156SSadaf Ebrahimi	cs_opt_type opt_type;
2850*9a0e4156SSadaf Ebrahimi	cs_opt_value opt_value;
2851*9a0e4156SSadaf Ebrahimi};
2852*9a0e4156SSadaf Ebrahimi
2853*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len)
2854*9a0e4156SSadaf Ebrahimi{
2855*9a0e4156SSadaf Ebrahimi	unsigned char* c;
2856*9a0e4156SSadaf Ebrahimi
2857*9a0e4156SSadaf Ebrahimi	printf("Code: ");
2858*9a0e4156SSadaf Ebrahimi	for (c = str; c < str + len; c++) {
2859*9a0e4156SSadaf Ebrahimi		printf("0x%02x ", *c & 0xff);
2860*9a0e4156SSadaf Ebrahimi	}
2861*9a0e4156SSadaf Ebrahimi	printf("\n");
2862*9a0e4156SSadaf Ebrahimi}
2863*9a0e4156SSadaf Ebrahimi
2864*9a0e4156SSadaf Ebrahimistatic void test()
2865*9a0e4156SSadaf Ebrahimi{
2866*9a0e4156SSadaf Ebrahimi
2867*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
2868*9a0e4156SSadaf Ebrahimi
2869*9a0e4156SSadaf Ebrahimi	struct platform platforms[] = {
2870*9a0e4156SSadaf Ebrahimi		{
2871*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
2872*9a0e4156SSadaf Ebrahimi			CS_MODE_64,
2873*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE64,
2874*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE64) - 1,
2875*9a0e4156SSadaf Ebrahimi			"X86 64 (Intel syntax)"
2876*9a0e4156SSadaf Ebrahimi		},
2877*9a0e4156SSadaf Ebrahimi	};
2878*9a0e4156SSadaf Ebrahimi
2879*9a0e4156SSadaf Ebrahimi	csh handle;
2880*9a0e4156SSadaf Ebrahimi	uint64_t address;
2881*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
2882*9a0e4156SSadaf Ebrahimi	cs_detail* detail;
2883*9a0e4156SSadaf Ebrahimi	int i;
2884*9a0e4156SSadaf Ebrahimi	cs_err err;
2885*9a0e4156SSadaf Ebrahimi	const uint8_t* code;
2886*9a0e4156SSadaf Ebrahimi	size_t size;
2887*9a0e4156SSadaf Ebrahimi
2888*9a0e4156SSadaf Ebrahimi	for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
2889*9a0e4156SSadaf Ebrahimi		printf("****************\n");
2890*9a0e4156SSadaf Ebrahimi		printf("Platform: %s\n", platforms[i].comment);
2891*9a0e4156SSadaf Ebrahimi		err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
2892*9a0e4156SSadaf Ebrahimi		if (err) {
2893*9a0e4156SSadaf Ebrahimi			printf("Failed on cs_open() with error returned: %u\n", err);
2894*9a0e4156SSadaf Ebrahimi			abort();
2895*9a0e4156SSadaf Ebrahimi		}
2896*9a0e4156SSadaf Ebrahimi
2897*9a0e4156SSadaf Ebrahimi		if (platforms[i].opt_type)
2898*9a0e4156SSadaf Ebrahimi			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
2899*9a0e4156SSadaf Ebrahimi
2900*9a0e4156SSadaf Ebrahimi		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
2901*9a0e4156SSadaf Ebrahimi
2902*9a0e4156SSadaf Ebrahimi		insn = cs_malloc(handle);
2903*9a0e4156SSadaf Ebrahimi
2904*9a0e4156SSadaf Ebrahimi		print_string_hex(platforms[i].code, platforms[i].size);
2905*9a0e4156SSadaf Ebrahimi		printf("Disasm:\n");
2906*9a0e4156SSadaf Ebrahimi
2907*9a0e4156SSadaf Ebrahimi		address = 0x1000;
2908*9a0e4156SSadaf Ebrahimi		code = platforms[i].code;
2909*9a0e4156SSadaf Ebrahimi		size = platforms[i].size;
2910*9a0e4156SSadaf Ebrahimi		while (cs_disasm_iter(handle, &code, &size, &address, insn)) {
2911*9a0e4156SSadaf Ebrahimi			int n;
2912*9a0e4156SSadaf Ebrahimi
2913*9a0e4156SSadaf Ebrahimi			printf("0x%" PRIx64 ":\t%s\t\t%s          ",
2914*9a0e4156SSadaf Ebrahimi				insn->address, insn->mnemonic, insn->op_str);
2915*9a0e4156SSadaf Ebrahimi			cout << "is REG:   " << cs_op_count(handle, insn, X86_OP_REG) << endl;   //判断是否为寄存操作码
2916*9a0e4156SSadaf Ebrahimi			cout << endl;
2917*9a0e4156SSadaf Ebrahimi
2918*9a0e4156SSadaf Ebrahimi		printf("\n");
2919*9a0e4156SSadaf Ebrahimi		cs_free(insn, 1);
2920*9a0e4156SSadaf Ebrahimi		cs_close(&handle);
2921*9a0e4156SSadaf Ebrahimi	}
2922*9a0e4156SSadaf Ebrahimi}
2923*9a0e4156SSadaf Ebrahimi
2924*9a0e4156SSadaf Ebrahimiint main()
2925*9a0e4156SSadaf Ebrahimi{
2926*9a0e4156SSadaf Ebrahimi	test();
2927*9a0e4156SSadaf Ebrahimi
2928*9a0e4156SSadaf Ebrahimi	return 0;
2929*9a0e4156SSadaf Ebrahimi}
2930*9a0e4156SSadaf Ebrahimi```
2931*9a0e4156SSadaf Ebrahimi
2932*9a0e4156SSadaf Ebrahimi</details>
2933*9a0e4156SSadaf Ebrahimi
2934*9a0e4156SSadaf Ebrahimi输出
2935*9a0e4156SSadaf Ebrahimi
2936*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/24.jpg)
2937*9a0e4156SSadaf Ebrahimi
2938*9a0e4156SSadaf Ebrahimi
2939*9a0e4156SSadaf Ebrahimi### cs_op_index
2940*9a0e4156SSadaf Ebrahimi
2941*9a0e4156SSadaf Ebrahimi`int CAPSTONE_API cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type, unsigned int position);`
2942*9a0e4156SSadaf Ebrahimi
2943*9a0e4156SSadaf Ebrahimi检索给定类型的操作数在`<arch>.operands[]`数组中的位置, 使用返回的位置访问操作数
2944*9a0e4156SSadaf Ebrahimi
2945*9a0e4156SSadaf Ebrahimi注意:只有当detail选项为ON时这个API可用 (默认OFF).
2946*9a0e4156SSadaf Ebrahimi
2947*9a0e4156SSadaf Ebrahimi```
2948*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
2949*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()接收的反汇编指令结构
2950*9a0e4156SSadaf Ebrahimiop_type: 要找到的操作数类型。
2951*9a0e4156SSadaf Ebrahimiposition: 要查找的操作数的位置。范围一定在`[1, cs_op_count(handle, insn, op_type)]`内
2952*9a0e4156SSadaf Ebrahimireturn: 指令insn的`<arch>.operands[]`数组中给定类型op_type的操作数的索引,失败时返回-1。
2953*9a0e4156SSadaf Ebrahimi```
2954*9a0e4156SSadaf Ebrahimi
2955*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
2956*9a0e4156SSadaf Ebrahimi
2957*9a0e4156SSadaf Ebrahimi```cpp
2958*9a0e4156SSadaf Ebrahimiint CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type,
2959*9a0e4156SSadaf Ebrahimi		unsigned int post)
2960*9a0e4156SSadaf Ebrahimi{
2961*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
2962*9a0e4156SSadaf Ebrahimi	unsigned int count = 0, i;
2963*9a0e4156SSadaf Ebrahimi	if (!ud)
2964*9a0e4156SSadaf Ebrahimi		return -1;
2965*9a0e4156SSadaf Ebrahimi
2966*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
2967*9a0e4156SSadaf Ebrahimi
2968*9a0e4156SSadaf Ebrahimi	if (!handle->detail) {
2969*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2970*9a0e4156SSadaf Ebrahimi		return -1;
2971*9a0e4156SSadaf Ebrahimi	}
2972*9a0e4156SSadaf Ebrahimi
2973*9a0e4156SSadaf Ebrahimi	if (!insn->id) {
2974*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_SKIPDATA;
2975*9a0e4156SSadaf Ebrahimi		return -1;
2976*9a0e4156SSadaf Ebrahimi	}
2977*9a0e4156SSadaf Ebrahimi
2978*9a0e4156SSadaf Ebrahimi	if (!insn->detail) {
2979*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
2980*9a0e4156SSadaf Ebrahimi		return -1;
2981*9a0e4156SSadaf Ebrahimi	}
2982*9a0e4156SSadaf Ebrahimi
2983*9a0e4156SSadaf Ebrahimi	handle->errnum = CS_ERR_OK;
2984*9a0e4156SSadaf Ebrahimi
2985*9a0e4156SSadaf Ebrahimi	switch (handle->arch) {
2986*9a0e4156SSadaf Ebrahimi		default:
2987*9a0e4156SSadaf Ebrahimi			handle->errnum = CS_ERR_HANDLE;
2988*9a0e4156SSadaf Ebrahimi			return -1;
2989*9a0e4156SSadaf Ebrahimi		case CS_ARCH_ARM:
2990*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->arm.op_count; i++) {
2991*9a0e4156SSadaf Ebrahimi				if (insn->detail->arm.operands[i].type == (arm_op_type)op_type)
2992*9a0e4156SSadaf Ebrahimi					count++;
2993*9a0e4156SSadaf Ebrahimi				if (count == post)
2994*9a0e4156SSadaf Ebrahimi					return i;
2995*9a0e4156SSadaf Ebrahimi			}
2996*9a0e4156SSadaf Ebrahimi			break;
2997*9a0e4156SSadaf Ebrahimi		case CS_ARCH_ARM64:
2998*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->arm64.op_count; i++) {
2999*9a0e4156SSadaf Ebrahimi				if (insn->detail->arm64.operands[i].type == (arm64_op_type)op_type)
3000*9a0e4156SSadaf Ebrahimi					count++;
3001*9a0e4156SSadaf Ebrahimi				if (count == post)
3002*9a0e4156SSadaf Ebrahimi					return i;
3003*9a0e4156SSadaf Ebrahimi			}
3004*9a0e4156SSadaf Ebrahimi			break;
3005*9a0e4156SSadaf Ebrahimi		case CS_ARCH_X86:
3006*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->x86.op_count; i++) {
3007*9a0e4156SSadaf Ebrahimi				if (insn->detail->x86.operands[i].type == (x86_op_type)op_type)
3008*9a0e4156SSadaf Ebrahimi					count++;
3009*9a0e4156SSadaf Ebrahimi				if (count == post)
3010*9a0e4156SSadaf Ebrahimi					return i;
3011*9a0e4156SSadaf Ebrahimi			}
3012*9a0e4156SSadaf Ebrahimi			break;
3013*9a0e4156SSadaf Ebrahimi		case CS_ARCH_MIPS:
3014*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->mips.op_count; i++) {
3015*9a0e4156SSadaf Ebrahimi				if (insn->detail->mips.operands[i].type == (mips_op_type)op_type)
3016*9a0e4156SSadaf Ebrahimi					count++;
3017*9a0e4156SSadaf Ebrahimi				if (count == post)
3018*9a0e4156SSadaf Ebrahimi					return i;
3019*9a0e4156SSadaf Ebrahimi			}
3020*9a0e4156SSadaf Ebrahimi			break;
3021*9a0e4156SSadaf Ebrahimi		case CS_ARCH_PPC:
3022*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->ppc.op_count; i++) {
3023*9a0e4156SSadaf Ebrahimi				if (insn->detail->ppc.operands[i].type == (ppc_op_type)op_type)
3024*9a0e4156SSadaf Ebrahimi					count++;
3025*9a0e4156SSadaf Ebrahimi				if (count == post)
3026*9a0e4156SSadaf Ebrahimi					return i;
3027*9a0e4156SSadaf Ebrahimi			}
3028*9a0e4156SSadaf Ebrahimi			break;
3029*9a0e4156SSadaf Ebrahimi		case CS_ARCH_SPARC:
3030*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->sparc.op_count; i++) {
3031*9a0e4156SSadaf Ebrahimi				if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type)
3032*9a0e4156SSadaf Ebrahimi					count++;
3033*9a0e4156SSadaf Ebrahimi				if (count == post)
3034*9a0e4156SSadaf Ebrahimi					return i;
3035*9a0e4156SSadaf Ebrahimi			}
3036*9a0e4156SSadaf Ebrahimi			break;
3037*9a0e4156SSadaf Ebrahimi		case CS_ARCH_SYSZ:
3038*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->sysz.op_count; i++) {
3039*9a0e4156SSadaf Ebrahimi				if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type)
3040*9a0e4156SSadaf Ebrahimi					count++;
3041*9a0e4156SSadaf Ebrahimi				if (count == post)
3042*9a0e4156SSadaf Ebrahimi					return i;
3043*9a0e4156SSadaf Ebrahimi			}
3044*9a0e4156SSadaf Ebrahimi			break;
3045*9a0e4156SSadaf Ebrahimi		case CS_ARCH_XCORE:
3046*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->xcore.op_count; i++) {
3047*9a0e4156SSadaf Ebrahimi				if (insn->detail->xcore.operands[i].type == (xcore_op_type)op_type)
3048*9a0e4156SSadaf Ebrahimi					count++;
3049*9a0e4156SSadaf Ebrahimi				if (count == post)
3050*9a0e4156SSadaf Ebrahimi					return i;
3051*9a0e4156SSadaf Ebrahimi			}
3052*9a0e4156SSadaf Ebrahimi			break;
3053*9a0e4156SSadaf Ebrahimi		case CS_ARCH_M68K:
3054*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->m68k.op_count; i++) {
3055*9a0e4156SSadaf Ebrahimi				if (insn->detail->m68k.operands[i].type == (m68k_op_type)op_type)
3056*9a0e4156SSadaf Ebrahimi					count++;
3057*9a0e4156SSadaf Ebrahimi				if (count == post)
3058*9a0e4156SSadaf Ebrahimi					return i;
3059*9a0e4156SSadaf Ebrahimi			}
3060*9a0e4156SSadaf Ebrahimi			break;
3061*9a0e4156SSadaf Ebrahimi		case CS_ARCH_TMS320C64X:
3062*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->tms320c64x.op_count; i++) {
3063*9a0e4156SSadaf Ebrahimi				if (insn->detail->tms320c64x.operands[i].type == (tms320c64x_op_type)op_type)
3064*9a0e4156SSadaf Ebrahimi					count++;
3065*9a0e4156SSadaf Ebrahimi				if (count == post)
3066*9a0e4156SSadaf Ebrahimi					return i;
3067*9a0e4156SSadaf Ebrahimi			}
3068*9a0e4156SSadaf Ebrahimi			break;
3069*9a0e4156SSadaf Ebrahimi		case CS_ARCH_M680X:
3070*9a0e4156SSadaf Ebrahimi			for (i = 0; i < insn->detail->m680x.op_count; i++) {
3071*9a0e4156SSadaf Ebrahimi				if (insn->detail->m680x.operands[i].type == (m680x_op_type)op_type)
3072*9a0e4156SSadaf Ebrahimi					count++;
3073*9a0e4156SSadaf Ebrahimi				if (count == post)
3074*9a0e4156SSadaf Ebrahimi					return i;
3075*9a0e4156SSadaf Ebrahimi			}
3076*9a0e4156SSadaf Ebrahimi			break;
3077*9a0e4156SSadaf Ebrahimi	}
3078*9a0e4156SSadaf Ebrahimi
3079*9a0e4156SSadaf Ebrahimi	return -1;
3080*9a0e4156SSadaf Ebrahimi}
3081*9a0e4156SSadaf Ebrahimi```
3082*9a0e4156SSadaf Ebrahimi</details>
3083*9a0e4156SSadaf Ebrahimi
3084*9a0e4156SSadaf Ebrahimi
3085*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary>
3086*9a0e4156SSadaf Ebrahimi
3087*9a0e4156SSadaf Ebrahimi```cpp
3088*9a0e4156SSadaf Ebrahimi#include <iostream>
3089*9a0e4156SSadaf Ebrahimi#include <stdio.h>
3090*9a0e4156SSadaf Ebrahimi
3091*9a0e4156SSadaf Ebrahimi#include "capstone.h"
3092*9a0e4156SSadaf Ebrahimi#include "platform.h"
3093*9a0e4156SSadaf Ebrahimi
3094*9a0e4156SSadaf Ebrahimiusing namespace std;
3095*9a0e4156SSadaf Ebrahimi
3096*9a0e4156SSadaf Ebrahimistruct platform {
3097*9a0e4156SSadaf Ebrahimi	cs_arch arch;
3098*9a0e4156SSadaf Ebrahimi	cs_mode mode;
3099*9a0e4156SSadaf Ebrahimi	unsigned char* code;
3100*9a0e4156SSadaf Ebrahimi	size_t size;
3101*9a0e4156SSadaf Ebrahimi	const char* comment;
3102*9a0e4156SSadaf Ebrahimi	cs_opt_type opt_type;
3103*9a0e4156SSadaf Ebrahimi	cs_opt_value opt_value;
3104*9a0e4156SSadaf Ebrahimi};
3105*9a0e4156SSadaf Ebrahimi
3106*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len)
3107*9a0e4156SSadaf Ebrahimi{
3108*9a0e4156SSadaf Ebrahimi	unsigned char* c;
3109*9a0e4156SSadaf Ebrahimi
3110*9a0e4156SSadaf Ebrahimi	printf("Code: ");
3111*9a0e4156SSadaf Ebrahimi	for (c = str; c < str + len; c++) {
3112*9a0e4156SSadaf Ebrahimi		printf("0x%02x ", *c & 0xff);
3113*9a0e4156SSadaf Ebrahimi	}
3114*9a0e4156SSadaf Ebrahimi	printf("\n");
3115*9a0e4156SSadaf Ebrahimi}
3116*9a0e4156SSadaf Ebrahimi
3117*9a0e4156SSadaf Ebrahimistatic void test()
3118*9a0e4156SSadaf Ebrahimi{
3119*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
3120*9a0e4156SSadaf Ebrahimi	struct platform platforms[] = {
3121*9a0e4156SSadaf Ebrahimi		{
3122*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
3123*9a0e4156SSadaf Ebrahimi			CS_MODE_64,
3124*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE64,
3125*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE64) - 1,
3126*9a0e4156SSadaf Ebrahimi			"X86 64 (Intel syntax)"
3127*9a0e4156SSadaf Ebrahimi		},
3128*9a0e4156SSadaf Ebrahimi	};
3129*9a0e4156SSadaf Ebrahimi
3130*9a0e4156SSadaf Ebrahimi	csh handle;
3131*9a0e4156SSadaf Ebrahimi	uint64_t address;
3132*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
3133*9a0e4156SSadaf Ebrahimi	cs_detail* detail;
3134*9a0e4156SSadaf Ebrahimi	int i;
3135*9a0e4156SSadaf Ebrahimi	cs_err err;
3136*9a0e4156SSadaf Ebrahimi	const uint8_t* code;
3137*9a0e4156SSadaf Ebrahimi	size_t size;
3138*9a0e4156SSadaf Ebrahimi
3139*9a0e4156SSadaf Ebrahimi	cs_x86* x86;
3140*9a0e4156SSadaf Ebrahimi
3141*9a0e4156SSadaf Ebrahimi	int count;
3142*9a0e4156SSadaf Ebrahimi
3143*9a0e4156SSadaf Ebrahimi	for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
3144*9a0e4156SSadaf Ebrahimi		printf("****************\n");
3145*9a0e4156SSadaf Ebrahimi		printf("Platform: %s\n", platforms[i].comment);
3146*9a0e4156SSadaf Ebrahimi		err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
3147*9a0e4156SSadaf Ebrahimi		if (err) {
3148*9a0e4156SSadaf Ebrahimi			printf("Failed on cs_open() with error returned: %u\n", err);
3149*9a0e4156SSadaf Ebrahimi			abort();
3150*9a0e4156SSadaf Ebrahimi		}
3151*9a0e4156SSadaf Ebrahimi
3152*9a0e4156SSadaf Ebrahimi		if (platforms[i].opt_type)
3153*9a0e4156SSadaf Ebrahimi			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
3154*9a0e4156SSadaf Ebrahimi
3155*9a0e4156SSadaf Ebrahimi		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
3156*9a0e4156SSadaf Ebrahimi
3157*9a0e4156SSadaf Ebrahimi		insn = cs_malloc(handle);
3158*9a0e4156SSadaf Ebrahimi		x86 = &(insn->detail->x86);
3159*9a0e4156SSadaf Ebrahimi		print_string_hex(platforms[i].code, platforms[i].size);
3160*9a0e4156SSadaf Ebrahimi		printf("Disasm:\n");
3161*9a0e4156SSadaf Ebrahimi
3162*9a0e4156SSadaf Ebrahimi		address = 0x1000;
3163*9a0e4156SSadaf Ebrahimi		code = platforms[i].code;
3164*9a0e4156SSadaf Ebrahimi		size = platforms[i].size;
3165*9a0e4156SSadaf Ebrahimi		while (cs_disasm_iter(handle, &code, &size, &address, insn)) {
3166*9a0e4156SSadaf Ebrahimi			int n;
3167*9a0e4156SSadaf Ebrahimi
3168*9a0e4156SSadaf Ebrahimi			printf("0x%" PRIx64 ":\t%s\t\t%s          ",
3169*9a0e4156SSadaf Ebrahimi				insn->address, insn->mnemonic, insn->op_str);
3170*9a0e4156SSadaf Ebrahimi			cout << endl;
3171*9a0e4156SSadaf Ebrahimi
3172*9a0e4156SSadaf Ebrahimi			count = cs_op_count(handle, insn, X86_OP_IMM);  //查找立即数
3173*9a0e4156SSadaf Ebrahimi			if (count) {
3174*9a0e4156SSadaf Ebrahimi				printf("\timm_count: %u\n", count);
3175*9a0e4156SSadaf Ebrahimi				for (i = 1; i < count + 1; i++) {
3176*9a0e4156SSadaf Ebrahimi					int index = cs_op_index(handle, insn, X86_OP_IMM, i);
3177*9a0e4156SSadaf Ebrahimi					printf("\timms[%u]: 0x%" PRIx64 "\n", i, x86->operands[index].imm);
3178*9a0e4156SSadaf Ebrahimi					if (x86->encoding.imm_offset != 0) {
3179*9a0e4156SSadaf Ebrahimi						printf("\timm_offset: 0x%x\n", x86->encoding.imm_offset);
3180*9a0e4156SSadaf Ebrahimi					}
3181*9a0e4156SSadaf Ebrahimi					if (x86->encoding.imm_size != 0) {
3182*9a0e4156SSadaf Ebrahimi						printf("\timm_size: 0x%x\n", x86->encoding.imm_size);
3183*9a0e4156SSadaf Ebrahimi					}
3184*9a0e4156SSadaf Ebrahimi				}
3185*9a0e4156SSadaf Ebrahimi			}
3186*9a0e4156SSadaf Ebrahimi		}
3187*9a0e4156SSadaf Ebrahimi
3188*9a0e4156SSadaf Ebrahimi		printf("\n");
3189*9a0e4156SSadaf Ebrahimi		cs_free(insn, 1);
3190*9a0e4156SSadaf Ebrahimi		cs_close(&handle);
3191*9a0e4156SSadaf Ebrahimi	}
3192*9a0e4156SSadaf Ebrahimi}
3193*9a0e4156SSadaf Ebrahimi
3194*9a0e4156SSadaf Ebrahimiint main()
3195*9a0e4156SSadaf Ebrahimi{
3196*9a0e4156SSadaf Ebrahimi	test();
3197*9a0e4156SSadaf Ebrahimi	return 0;
3198*9a0e4156SSadaf Ebrahimi}
3199*9a0e4156SSadaf Ebrahimi```
3200*9a0e4156SSadaf Ebrahimi
3201*9a0e4156SSadaf Ebrahimi</details>
3202*9a0e4156SSadaf Ebrahimi
3203*9a0e4156SSadaf Ebrahimi输出
3204*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/25.jpg)
3205*9a0e4156SSadaf Ebrahimi
3206*9a0e4156SSadaf Ebrahimi
3207*9a0e4156SSadaf Ebrahimi### cs_regs_access
3208*9a0e4156SSadaf Ebrahimi
3209*9a0e4156SSadaf Ebrahimi```cpp
3210*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_regs_access(csh handle, const cs_insn *insn,
3211*9a0e4156SSadaf Ebrahimi		cs_regs regs_read, uint8_t *regs_read_count,
3212*9a0e4156SSadaf Ebrahimi		cs_regs regs_write, uint8_t *regs_write_count);
3213*9a0e4156SSadaf Ebrahimi```
3214*9a0e4156SSadaf Ebrahimi
3215*9a0e4156SSadaf Ebrahimi检索由一条指令显式或隐式访问的所有寄存器
3216*9a0e4156SSadaf Ebrahimi
3217*9a0e4156SSadaf Ebrahimi注意: 在“diet”模式下,此API不可用,因为引擎不存储寄存器
3218*9a0e4156SSadaf Ebrahimi
3219*9a0e4156SSadaf Ebrahimi```
3220*9a0e4156SSadaf Ebrahimihandle: cs_open()返回的句柄
3221*9a0e4156SSadaf Ebrahimiinsn: 从cs_disasm()或cs_disasm_iter()返回的反汇编指令结构
3222*9a0e4156SSadaf Ebrahimiregs_read:返回时,这个数组包含所有按指令读取的寄存器。
3223*9a0e4156SSadaf Ebrahimiregs_read_count:保存在regs_read数组中的寄存器数。
3224*9a0e4156SSadaf Ebrahimiregs_write:返回时,这个数组包含所有由指令修改的寄存器。
3225*9a0e4156SSadaf Ebrahimiregs_write_count:保存在regs_write数组中的寄存器数。
3226*9a0e4156SSadaf Ebrahimi成功时返回CS_ERR_OK,失败时返回其他值(详细错误请参阅cs_err enum)。
3227*9a0e4156SSadaf Ebrahimi```
3228*9a0e4156SSadaf Ebrahimi
3229*9a0e4156SSadaf Ebrahimi<details><summary> 源码实现 </summary>
3230*9a0e4156SSadaf Ebrahimi
3231*9a0e4156SSadaf Ebrahimi```cpp
3232*9a0e4156SSadaf Ebrahimics_err CAPSTONE_API cs_regs_access(csh ud, const cs_insn *insn,
3233*9a0e4156SSadaf Ebrahimi		cs_regs regs_read, uint8_t *regs_read_count,
3234*9a0e4156SSadaf Ebrahimi		cs_regs regs_write, uint8_t *regs_write_count)
3235*9a0e4156SSadaf Ebrahimi{
3236*9a0e4156SSadaf Ebrahimi	struct cs_struct *handle;
3237*9a0e4156SSadaf Ebrahimi
3238*9a0e4156SSadaf Ebrahimi	if (!ud)
3239*9a0e4156SSadaf Ebrahimi		return -1;
3240*9a0e4156SSadaf Ebrahimi
3241*9a0e4156SSadaf Ebrahimi	handle = (struct cs_struct *)(uintptr_t)ud;
3242*9a0e4156SSadaf Ebrahimi
3243*9a0e4156SSadaf Ebrahimi#ifdef CAPSTONE_DIET
3244*9a0e4156SSadaf Ebrahimi	// This API does not work in DIET mode
3245*9a0e4156SSadaf Ebrahimi	handle->errnum = CS_ERR_DIET;
3246*9a0e4156SSadaf Ebrahimi	return CS_ERR_DIET;
3247*9a0e4156SSadaf Ebrahimi#else
3248*9a0e4156SSadaf Ebrahimi	if (!handle->detail) {
3249*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
3250*9a0e4156SSadaf Ebrahimi		return CS_ERR_DETAIL;
3251*9a0e4156SSadaf Ebrahimi	}
3252*9a0e4156SSadaf Ebrahimi
3253*9a0e4156SSadaf Ebrahimi	if (!insn->id) {
3254*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_SKIPDATA;
3255*9a0e4156SSadaf Ebrahimi		return CS_ERR_SKIPDATA;
3256*9a0e4156SSadaf Ebrahimi	}
3257*9a0e4156SSadaf Ebrahimi
3258*9a0e4156SSadaf Ebrahimi	if (!insn->detail) {
3259*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_DETAIL;
3260*9a0e4156SSadaf Ebrahimi		return CS_ERR_DETAIL;
3261*9a0e4156SSadaf Ebrahimi	}
3262*9a0e4156SSadaf Ebrahimi
3263*9a0e4156SSadaf Ebrahimi	if (handle->reg_access) {
3264*9a0e4156SSadaf Ebrahimi		handle->reg_access(insn, regs_read, regs_read_count, regs_write, regs_write_count);
3265*9a0e4156SSadaf Ebrahimi	} else {
3266*9a0e4156SSadaf Ebrahimi		// this arch is unsupported yet
3267*9a0e4156SSadaf Ebrahimi		handle->errnum = CS_ERR_ARCH;
3268*9a0e4156SSadaf Ebrahimi		return CS_ERR_ARCH;
3269*9a0e4156SSadaf Ebrahimi	}
3270*9a0e4156SSadaf Ebrahimi
3271*9a0e4156SSadaf Ebrahimi	return CS_ERR_OK;
3272*9a0e4156SSadaf Ebrahimi#endif
3273*9a0e4156SSadaf Ebrahimi}
3274*9a0e4156SSadaf Ebrahimi```
3275*9a0e4156SSadaf Ebrahimi
3276*9a0e4156SSadaf Ebrahimi</details>
3277*9a0e4156SSadaf Ebrahimi
3278*9a0e4156SSadaf Ebrahimi
3279*9a0e4156SSadaf Ebrahimi<details><summary> 示例 </summary>
3280*9a0e4156SSadaf Ebrahimi
3281*9a0e4156SSadaf Ebrahimi```cpp
3282*9a0e4156SSadaf Ebrahimi#include <iostream>
3283*9a0e4156SSadaf Ebrahimi#include <stdio.h>
3284*9a0e4156SSadaf Ebrahimi
3285*9a0e4156SSadaf Ebrahimi#include "capstone.h"
3286*9a0e4156SSadaf Ebrahimi#include "platform.h"
3287*9a0e4156SSadaf Ebrahimi
3288*9a0e4156SSadaf Ebrahimiusing namespace std;
3289*9a0e4156SSadaf Ebrahimi
3290*9a0e4156SSadaf Ebrahimistruct platform {
3291*9a0e4156SSadaf Ebrahimi	cs_arch arch;
3292*9a0e4156SSadaf Ebrahimi	cs_mode mode;
3293*9a0e4156SSadaf Ebrahimi	unsigned char* code;
3294*9a0e4156SSadaf Ebrahimi	size_t size;
3295*9a0e4156SSadaf Ebrahimi	const char* comment;
3296*9a0e4156SSadaf Ebrahimi	cs_opt_type opt_type;
3297*9a0e4156SSadaf Ebrahimi	cs_opt_value opt_value;
3298*9a0e4156SSadaf Ebrahimi};
3299*9a0e4156SSadaf Ebrahimi
3300*9a0e4156SSadaf Ebrahimistatic void print_string_hex(unsigned char* str, size_t len)
3301*9a0e4156SSadaf Ebrahimi{
3302*9a0e4156SSadaf Ebrahimi	unsigned char* c;
3303*9a0e4156SSadaf Ebrahimi
3304*9a0e4156SSadaf Ebrahimi	printf("Code: ");
3305*9a0e4156SSadaf Ebrahimi	for (c = str; c < str + len; c++) {
3306*9a0e4156SSadaf Ebrahimi		printf("0x%02x ", *c & 0xff);
3307*9a0e4156SSadaf Ebrahimi	}
3308*9a0e4156SSadaf Ebrahimi	printf("\n");
3309*9a0e4156SSadaf Ebrahimi}
3310*9a0e4156SSadaf Ebrahimi
3311*9a0e4156SSadaf Ebrahimistatic void test()
3312*9a0e4156SSadaf Ebrahimi{
3313*9a0e4156SSadaf Ebrahimi#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
3314*9a0e4156SSadaf Ebrahimi	struct platform platforms[] = {
3315*9a0e4156SSadaf Ebrahimi		{
3316*9a0e4156SSadaf Ebrahimi			CS_ARCH_X86,
3317*9a0e4156SSadaf Ebrahimi			CS_MODE_64,
3318*9a0e4156SSadaf Ebrahimi			(unsigned char*)X86_CODE64,
3319*9a0e4156SSadaf Ebrahimi			sizeof(X86_CODE64) - 1,
3320*9a0e4156SSadaf Ebrahimi			"X86 64 (Intel syntax)"
3321*9a0e4156SSadaf Ebrahimi		},
3322*9a0e4156SSadaf Ebrahimi	};
3323*9a0e4156SSadaf Ebrahimi
3324*9a0e4156SSadaf Ebrahimi	csh handle;
3325*9a0e4156SSadaf Ebrahimi	uint64_t address;
3326*9a0e4156SSadaf Ebrahimi	cs_insn* insn;
3327*9a0e4156SSadaf Ebrahimi	cs_detail* detail;
3328*9a0e4156SSadaf Ebrahimi	int i;
3329*9a0e4156SSadaf Ebrahimi	cs_err err;
3330*9a0e4156SSadaf Ebrahimi	const uint8_t* code;
3331*9a0e4156SSadaf Ebrahimi	size_t size;
3332*9a0e4156SSadaf Ebrahimi
3333*9a0e4156SSadaf Ebrahimi	cs_x86* x86;
3334*9a0e4156SSadaf Ebrahimi	cs_regs regs_read, regs_write;
3335*9a0e4156SSadaf Ebrahimi	uint8_t regs_read_count, regs_write_count;
3336*9a0e4156SSadaf Ebrahimi
3337*9a0e4156SSadaf Ebrahimi	int count;
3338*9a0e4156SSadaf Ebrahimi
3339*9a0e4156SSadaf Ebrahimi	for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
3340*9a0e4156SSadaf Ebrahimi		printf("****************\n");
3341*9a0e4156SSadaf Ebrahimi		printf("Platform: %s\n", platforms[i].comment);
3342*9a0e4156SSadaf Ebrahimi		err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
3343*9a0e4156SSadaf Ebrahimi		if (err) {
3344*9a0e4156SSadaf Ebrahimi			printf("Failed on cs_open() with error returned: %u\n", err);
3345*9a0e4156SSadaf Ebrahimi			abort();
3346*9a0e4156SSadaf Ebrahimi		}
3347*9a0e4156SSadaf Ebrahimi
3348*9a0e4156SSadaf Ebrahimi		if (platforms[i].opt_type)
3349*9a0e4156SSadaf Ebrahimi			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
3350*9a0e4156SSadaf Ebrahimi
3351*9a0e4156SSadaf Ebrahimi		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
3352*9a0e4156SSadaf Ebrahimi
3353*9a0e4156SSadaf Ebrahimi		insn = cs_malloc(handle);
3354*9a0e4156SSadaf Ebrahimi		x86 = &(insn->detail->x86);
3355*9a0e4156SSadaf Ebrahimi		print_string_hex(platforms[i].code, platforms[i].size);
3356*9a0e4156SSadaf Ebrahimi		printf("Disasm:\n");
3357*9a0e4156SSadaf Ebrahimi
3358*9a0e4156SSadaf Ebrahimi		address = 0x1000;
3359*9a0e4156SSadaf Ebrahimi		code = platforms[i].code;
3360*9a0e4156SSadaf Ebrahimi		size = platforms[i].size;
3361*9a0e4156SSadaf Ebrahimi		while (cs_disasm_iter(handle, &code, &size, &address, insn)) {
3362*9a0e4156SSadaf Ebrahimi			int n;
3363*9a0e4156SSadaf Ebrahimi
3364*9a0e4156SSadaf Ebrahimi			printf("0x%" PRIx64 ":\t%s\t\t%s          ",
3365*9a0e4156SSadaf Ebrahimi				insn->address, insn->mnemonic, insn->op_str);
3366*9a0e4156SSadaf Ebrahimi			cout << endl;
3367*9a0e4156SSadaf Ebrahimi
3368*9a0e4156SSadaf Ebrahimi			if (!cs_regs_access(handle, insn,       //每条指令所有读取和修改的寄存器
3369*9a0e4156SSadaf Ebrahimi				regs_read, &regs_read_count,
3370*9a0e4156SSadaf Ebrahimi				regs_write, &regs_write_count)) {
3371*9a0e4156SSadaf Ebrahimi				if (regs_read_count) {
3372*9a0e4156SSadaf Ebrahimi					printf("\tRegisters read:");
3373*9a0e4156SSadaf Ebrahimi					for (i = 0; i < regs_read_count; i++) {
3374*9a0e4156SSadaf Ebrahimi						printf(" %s", cs_reg_name(handle, regs_read[i]));
3375*9a0e4156SSadaf Ebrahimi					}
3376*9a0e4156SSadaf Ebrahimi					printf("\n");
3377*9a0e4156SSadaf Ebrahimi				}
3378*9a0e4156SSadaf Ebrahimi
3379*9a0e4156SSadaf Ebrahimi				if (regs_write_count) {
3380*9a0e4156SSadaf Ebrahimi					printf("\tRegisters modified:");
3381*9a0e4156SSadaf Ebrahimi					for (i = 0; i < regs_write_count; i++) {
3382*9a0e4156SSadaf Ebrahimi						printf(" %s", cs_reg_name(handle, regs_write[i]));
3383*9a0e4156SSadaf Ebrahimi					}
3384*9a0e4156SSadaf Ebrahimi					printf("\n");
3385*9a0e4156SSadaf Ebrahimi				}
3386*9a0e4156SSadaf Ebrahimi			}
3387*9a0e4156SSadaf Ebrahimi		}
3388*9a0e4156SSadaf Ebrahimi
3389*9a0e4156SSadaf Ebrahimi		printf("\n");
3390*9a0e4156SSadaf Ebrahimi		cs_free(insn, 1);
3391*9a0e4156SSadaf Ebrahimi		cs_close(&handle);
3392*9a0e4156SSadaf Ebrahimi	}
3393*9a0e4156SSadaf Ebrahimi}
3394*9a0e4156SSadaf Ebrahimi
3395*9a0e4156SSadaf Ebrahimiint main()
3396*9a0e4156SSadaf Ebrahimi{
3397*9a0e4156SSadaf Ebrahimi	test();
3398*9a0e4156SSadaf Ebrahimi	return 0;
3399*9a0e4156SSadaf Ebrahimi}
3400*9a0e4156SSadaf Ebrahimi```
3401*9a0e4156SSadaf Ebrahimi
3402*9a0e4156SSadaf Ebrahimi</details>
3403*9a0e4156SSadaf Ebrahimi
3404*9a0e4156SSadaf Ebrahimi输出
3405*9a0e4156SSadaf Ebrahimi
3406*9a0e4156SSadaf Ebrahimi![](API_Doc_Pic/26.jpg)
3407